使用TypeScript的条件类型

时间:2018-09-05 00:27:23

标签: typescript tsc typescript3.0

说我有这个:

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,依此类推。

2 个答案:

答案 0 :(得分:5)

您可以像在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} | ...

答案 1 :(得分:2)

您必须告诉打字稿以某种方式验证实际的obj,并且如果不使用泛型就无法真正逃脱;这就是我的方法:

propSatisfies