一个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
    }
}

评论

0 / 800
全部评论()