使用 TypeScript 的条件类型
Posted
技术标签:
【中文标题】使用 TypeScript 的条件类型【英文标题】:Conditional types with TypeScript 【发布时间】:2019-02-10 00:44:59 【问题描述】:说我有这个:
type TypeMapping =
Boolean: boolean,
String: string,
Number: number,
ArrayOfString: Array<string>,
ArrayOfBoolean: Array<boolean>
export interface ElemType
foo: keyof TypeMapping,
default: valueof TypeMapping
我想有条件地定义它,而不是默认使用any
,我试过这个:
export interface ElemType<T extends TypeMapping>
foo: keyof T,
default: T
但这似乎不太正确,有人知道正确的方法吗?
如果不清楚,对于任何具有 ElemType 类型的给定对象,foo 指向的键必须与 foo 指向的值匹配。例如,这是有效的:
foo: 'String',
default: 'this is a string'
但这不是:
foo: 'Boolean',
default: 'this should be a boolean instead'
所以默认字段的类型是以类型字段的值/类型为条件的。
简而言之,如果foo
是'ArrayOfBoolean'
,那么default
应该是:Array<boolean>
。如果foo
是'Number'
,那么默认应该是number
,如果foo 是'Boolean'
,那么默认应该是boolean
,等等
【问题讨论】:
javascript Conditional Inside TypeScript Interface的可能重复 我更新了 OP,问题似乎有所不同,或者至少该问题的答案不够充分 【参考方案1】:您可以在 Catalyst 的答案中定义 ElemType
,然后使用映射类型将 ElemType
的并集用于所有可能的 K
:
interface ElemType<K extends keyof TypeMapping>
foo: K;
default: TypeMapping[K];
type ElemTypeMap = [K in keyof TypeMapping]: ElemType<K>;
// type ElemTypeMap =
// Boolean: foo: "Boolean", default: boolean,
// String: foo: "String", default: string,
// ...
//
type SomeElemType = ElemTypeMap[keyof TypeMapping];
// Look up in ElemTypeMap by all keys and take the union:
// foo: "Boolean", default: boolean | foo: "String", default: string | ...
【讨论】:
不完全确定你最后一行在做什么 - 不知道访问器部分是什么 - 你有一个标准接口
但随后访问了 []
这是indexed access type。当[]
中的类型是多个键的并集时,它会生成这些键的值类型的并集。请参阅更新的答案。如果还不清楚,请告诉我。【参考方案2】:
你必须告诉 typescript 以某种方式验证实际的 obj,如果不使用泛型,你就无法真正逃脱;我会这样做:
type TypeMapping =
Boolean: boolean;
String: string;
Number: number;
ArrayOfString: Array<string>;
;
export interface ElemType<K extends keyof TypeMapping>
foo: K;
default: TypeMapping[K];
const Elem = <E extends keyof TypeMapping, T extends ElemType<E>>(t: ElemType<E>) => t;
Elem( foo: "Boolean", default: true ); //yup
Elem( foo: "Boolean", default: "" ); //nope
【讨论】:
以上是关于使用 TypeScript 的条件类型的主要内容,如果未能解决你的问题,请参考以下文章
mongoose virtuals with typescript error - 包含箭头函数捕获“this”的全局值,该值隐含类型为“any”