一个typescript的类型推导问题
问题1
interface Cat {
type: 'cat';
}
interface Dog {
type: 'dog';
}
type LookUp<U extends { type: string },K> = U['type'] extends K ? 1 : 2;
type MyDog = LookUp<Dog, 'dog'>; // MyDog:1
type DogCag = LookUp<Dog | Cat, 'dog'> // DogCag: 2 理应 1 | 2
简化代码
// 具体类型推导
type t = 'cat' | 'dog' extends 'cat' ? 1 : 2; // t:2
// 泛型类型推导
type t2<T> = T extends 'cat' ? 1 : 2;
type t3 = t2<'cat'|'dog'>; // t3:1|2
从例子可以看出泛型和具体的类型所推导出来的类型是不一样的,只有类型是泛型才会推导出1|2
这种类型,而U['type']
并不是一个泛型。
所以可以把一个type
分成两步,第一步通过TypeType
获取联合类型,再把联合类型当成泛型传进LookUp
即可得到1|2
。
最终
type LookUp<U , k> = U extends k ? 1 : 2;
type TypeType<U extends { type: string }> = U['type'];
type DogCag = LookUp<TypeType<Dog | Cat>, 'dog'> // DogCag:1 | 2
第二个类似的问题
export interface SchemaBase {
modify_time: string;
}
class BaseClass<T extends SchemaBase> {
func = () => {
const test: T['modify_time'] = '123';
type Test = T['modify_time'] extends string ? true : false;
const boolVal: Test = true; // error
}
}
更奇怪的是,下面这个例子也会报错
class BaseClass<T extends SchemaBase> {
func = () => {
type Test = T extends SchemaBase ? true : false;
const boolVal: Test = true; // error
}
}
评论