我想学习使用条件类型试图推断签名中类型的类型的算法。
示例1:这里的正确地推断了T为number
type Args<T> = { value: T }
function foo<T>(args: Args<T>) { return args; }
// correctly inferred as foo<number>
foo({ value: 123 });示例2:条件类型和推断unknown
type StringOrNever<T> = T extends string ? string : never;
type Args<T> = { value: StringOrNever<T>; }
function foo<T>(args: Args<T>) { return args; }
// both calls inferred as foo<unknown> :(
foo({ value: 123 });
foo({ value: "some string" });示例3:正确(或“预期”)推断但类型怪异
type StringOrNever<T> = T extends string ? string : never;
type Args<T> = { value: StringOrNever<T> & T; }
function foo<T>(args: Args<T>) { return args; }
// inferred as foo<number>
foo({ value: 123 });
// inferred as foo<"Typescript">
foo({ value: "Typescript" });我想知道的是:
unknown,以及为什么会像我在示例(3)中所期望的那样推断T的类型?unknown (有点像最后的手段)。发布于 2022-08-29 16:24:54
泛型类型推断在TypeScript中是一个复杂且有时难以理解的概念。但是,泛型类型必须在可以由给定参数的类型替换的位置使用。
所以,例如,1
function foo<T>(args: { value: T }) { return args; }如果您传递一个{ value: string }类型的值,我们可以用string代替T。
例2也不能这样说。
type StringOrNever<T> = T extends string ? string : never;
function foo<T>(args: { value: StringOrNever<T> }) { return args; }T只用于比较部分的内容。在条件的右侧,我们只有string和never。T不在任何可以被给定类型替换的位置,因此unknown被推断为默认类型。
如果希望推理成功,则需要将T放在条件的右侧。
type StringOrNever<T> = T extends string ? T : never;
function foo<T>(args: { value: StringOrNever<T> }) { return args; }这允许TypeScript根据给定类型的value推断T。
https://stackoverflow.com/questions/73530465
复制相似问题