打字稿条件类型和分支缩小
Typescript conditionnal type and branch narrowing
使用此代码
type Identity <T extends string> = T;
type MaybeString = string | undefined;
type StringOrNever = MaybeString extends undefined ? never : Identity<MaybeString>;
当使用 MaybeString 作为 Identity 参数时,编译器抱怨无法将 undefined 分配给类型 String。
想知道这是否与条件类型的分配属性有关,我试了一下
type StringOrNever = [MaybeString] extends [undefined] ? [never] : Identity<MaybeString>;
这也不行。
我做错了什么?
这与分配无关。
Distributive conditional types作用于泛型。 StringOrNever
中的 MaybeString
不是通用的。
MaybeString extends undefined
不会缩小到 string
。在这种情况下,MaybeString
仍然是 string | undefined
。
为了使其工作,您应该参数化 StringOrNever
。
看这个例子:
type Identity<T extends string> = T;
type MaybeString = string | undefined;
type StringOrNever<T extends string | undefined> = T extends string ? Identity<T> : never
type Result1 = StringOrNever<'Hello'> // hello
type Result2 = StringOrNever<undefined> // never
type Result3 = StringOrNever<undefined | 'some stirng'> // 'some string'
Result3
有一个有趣的案例。事实上,Result3
是字符串的并集,从不:"some string" | never
。在这种情况下,never
与 string
发生冲突。那么,你想如何处理 union ?我们可以像您一样关闭分配性
type Identity<T extends string> = T;
type MaybeString = string | undefined;
type StringOrNever<T extends string | undefined> = [T] extends [string] ? Identity<T> : never
type Result1 = StringOrNever<'Hello'> // hello
type Result2 = StringOrNever<undefined> // never
type Result3 = StringOrNever<undefined | 'some stirng'> // never
使用此代码
type Identity <T extends string> = T;
type MaybeString = string | undefined;
type StringOrNever = MaybeString extends undefined ? never : Identity<MaybeString>;
当使用 MaybeString 作为 Identity 参数时,编译器抱怨无法将 undefined 分配给类型 String。
想知道这是否与条件类型的分配属性有关,我试了一下
type StringOrNever = [MaybeString] extends [undefined] ? [never] : Identity<MaybeString>;
这也不行。
我做错了什么?
这与分配无关。
Distributive conditional types作用于泛型。 StringOrNever
中的 MaybeString
不是通用的。
MaybeString extends undefined
不会缩小到 string
。在这种情况下,MaybeString
仍然是 string | undefined
。
为了使其工作,您应该参数化 StringOrNever
。
看这个例子:
type Identity<T extends string> = T;
type MaybeString = string | undefined;
type StringOrNever<T extends string | undefined> = T extends string ? Identity<T> : never
type Result1 = StringOrNever<'Hello'> // hello
type Result2 = StringOrNever<undefined> // never
type Result3 = StringOrNever<undefined | 'some stirng'> // 'some string'
Result3
有一个有趣的案例。事实上,Result3
是字符串的并集,从不:"some string" | never
。在这种情况下,never
与 string
发生冲突。那么,你想如何处理 union ?我们可以像您一样关闭分配性
type Identity<T extends string> = T;
type MaybeString = string | undefined;
type StringOrNever<T extends string | undefined> = [T] extends [string] ? Identity<T> : never
type Result1 = StringOrNever<'Hello'> // hello
type Result2 = StringOrNever<undefined> // never
type Result3 = StringOrNever<undefined | 'some stirng'> // never