gpt4 book ai didi

TypeScript 联合类型推断失败

转载 作者:搜寻专家 更新时间:2023-10-30 21:12:18 25 4
gpt4 key购买 nike

似乎有时 TypeScript(最新版本)无法缩小联合类型,即使存在类型保护。此行为是错误还是功能:

前言:

// some config
interface Config {
name: string;
option1?: number;
option2?: boolean;
}

// arbitrary type
interface Entity {
a: number;
b: number;
}

// name aware type guard for entity property-to-config map
// some default config may be replaced with a property name
type TConfigSet<TData> = {
[P in keyof TData]: (Config & { name: P }) | P;
}

// example of TConfigSet usage
const EntityConfigs: TConfigSet<Entity> = {
a: {
name: 'a',
option2: true
},
b: 'b'
}

问题:

// this function compiles
function TypeLooseFieldToName(name: string | Config): string {
if (typeof name === 'string') return name;
else return name.name;
}

// this one doesn't
function TypeStrictFieldToName<TData>(name: keyof TData | { name: keyof TData }): keyof TData {
if (typeof name === 'string') return name;
else return name.name; // still keyof TData | { name: keyof TData }, should be shrinked to { name: keyof TData }
}

最佳答案

这似乎是类型检查器中的错误,因为 TypeScript 手册说“keyof T 类型被认为是 string 的子类型。”

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html

作为解决方法,可以反转类型保护以首先排除自定义类型:

function hasName(obj: string | { name: string }): obj is { name: string } {
return typeof obj.name === 'string';
}

function getName<TData>(name: keyof TData | { name: keyof TData }): keyof TData {
if (hasName(name)) return name.name;
else return name;
}

// compiles with valid keys
getName<Entity>('a');
getName<Entity>({ name: 'a' });

// doesn't compile with invalid keys
getName<Entity>('z');
getName<Entity>({ name: 'z' });

您可以在 GitHub 中搜索 TypeScript Issues 并提交一个新问题(如果之前没有解决):

https://github.com/Microsoft/TypeScript/issues

关于TypeScript 联合类型推断失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46058596/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com