We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
关键词:never类型、never类型应用
never 是其他任意类型的子类型的类型被称为底部类型(bottom type)。
never
在 TypeScript 中,never 类型便为空类型和底部类型。never 类型的变量无法被赋值,与其他类型求交集为自身,求并集不参与运算。
never在联合类型中会被过滤掉:
type Exclude<T, U> = T extends U ? never : T; // 相当于: type A = 'a' type A = Exclude<'x' | 'a', 'x' | 'y' | 'z'> T | never // 结果为T T & never // 结果为never
取一个映射类型中所有value为指定类型的key。例如,已知某个React组件的props类型,我需要“知道”(编程意义上)哪些参数是function类型。
interface SomeProps { a: string b: number c: (e: MouseEvent) => void d: (e: TouchEvent) => void } // 如何得到 'c' | 'd' ? type GetKeyByValueType<T, Condition> = { [K in keyof T]: T[K] extends Condition ? K : never } [keyof T]; type FunctionPropNames = GetKeyByValueType<SomeProps, Function>; // 'c' | 'd'
运算过程如下:
// 开始 { a: string b: number c: (e: MouseEvent) => void d: (e: TouchEvent) => void } // 第一步,条件映射 { a: never b: never c: 'c' d: 'd' } // 第二步,索引取值 never | never | 'c' | 'd' // never的性质 'c' | 'd'
举个具体点的例子,当你有一个 union type:
interface Foo { type: 'foo' } interface Bar { type: 'bar' } type All = Foo | Bar
在 switch 当中判断 type,TS 是可以收窄类型的 (discriminated union):
function handleValue(val: All) { switch (val.type) { case 'foo': // 这里 val 被收窄为 Foo break case 'bar': // val 在这里是 Bar break default: // val 在这里是 never const exhaustiveCheck: never = val break } }
注意在 default 里面我们把被收窄为 never 的 val 赋值给一个显式声明为 never 的变量。如果一切逻辑正确,那么这里应该能够编译通过。但是假如后来有一天你的同事改了 All 的类型:
type All = Foo | Bar | Baz
然而他忘记了在 handleValue 里面加上针对 Baz 的处理逻辑,这个时候在 default branch 里面 val 会被收窄为 Baz,导致无法赋值给 never,产生一个编译错误。所以通过这个办法,你可以确保 handleValue 总是穷尽 (exhaust) 了所有 All 的可能类型。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
关键词:never类型、never类型应用
never
是其他任意类型的子类型的类型被称为底部类型(bottom type)。在 TypeScript 中,
never
类型便为空类型和底部类型。never
类型的变量无法被赋值,与其他类型求交集为自身,求并集不参与运算。应用一: 联合类型中的过滤
never在联合类型中会被过滤掉:
取一个映射类型中所有value为指定类型的key。例如,已知某个React组件的props类型,我需要“知道”(编程意义上)哪些参数是function类型。
运算过程如下:
应用二:防御性编程
举个具体点的例子,当你有一个 union type:
在 switch 当中判断 type,TS 是可以收窄类型的 (discriminated union):
注意在 default 里面我们把被收窄为 never 的 val 赋值给一个显式声明为 never 的变量。如果一切逻辑正确,那么这里应该能够编译通过。但是假如后来有一天你的同事改了 All 的类型:
type All = Foo | Bar | Baz
然而他忘记了在 handleValue 里面加上针对 Baz 的处理逻辑,这个时候在 default branch 里面 val 会被收窄为 Baz,导致无法赋值给 never,产生一个编译错误。所以通过这个办法,你可以确保 handleValue 总是穷尽 (exhaust) 了所有 All 的可能类型。
The text was updated successfully, but these errors were encountered: