首页 > 解决方案 > 让 TypeScript 推断(部分或全部)泛型参数

问题描述

假设我有一个泛型类型Gen<T>

type Gen<T> = {
    t: T,
    x: boolean,
};

然后我有一些函数接受 aGen但不关心T类型:

function handleGen1(gen) {
    if (gen.x) {
        return gen;
    }
}

我将如何打字handleGen1?目前我只能这样看:

function handleGen1<T>(gen: Gen<T>) {
    if (gen.x) {
        return gen;
    }
}

有没有更清洁的方法,比如Flow ( function handleGen1(gen: Gen<*>) { ... })?

另外,如果我的函数只依赖于一些类型参数怎么办?

type Gen<P, E> = {
  p: P,
  e: E,
  x: boolean,
}

function handleGen2(gen) {
    if (gen.x) {
        return gen.p;
    }
}

我想将其输入为:

handleGen2: (gen: Gen<P, *>) => P;

标签: typescript

解决方案


没有等同*于打字稿中的语法。您在声明类型参数时找到的选项是一个很好的选项。请注意,在调用站点不必指定额外参数,打字稿将推断出适当的T

type Gen<T> = {
    t: T,
    x: boolean,
};

function handleGen1<T>(gen: Gen<T>) {
    if (gen.x) {
        return gen;
    }
}

handleGen1({
    t: 1,
    x: true
}) // T infered as number

如果您有更多参数,Gen您将为每个类型参数声明一个:

type Gen<T, P> = {
    t: T,
    p: P,
    x: boolean,
};

function handleGen1<T, P>(gen: Gen<T, P>) {
    if (gen.x) {
        return gen;
    }
}

handleGen1({
    t: 1,
    p: "",
    x: true
}) // T inferred as number, P number

现在,如果您真的不在任何其他位置使用类型参数,您可以使用Gen<any>or Gen<unknown>。在您的示例中,您确实使用了,因为T返回类型将不会转发类型参数。如果不是这种情况,我们可以使用此选项:Gen<T>Gen<any>

type Gen<T> = {
    t: T,
    x: boolean,
};

function handleGen1(gen: Gen<unknown>) {
    if (gen.x) {
        console.log(gen.t);
    }
}

handleGen1({
    t: 1,
    x: true
}) // works fine 1 is assignable to unknown 

必须指定类型参数的一个缺点是还必须指定类型约束。


推荐阅读