让TypeScript推断(部分或全部)通用参数

时间:2018-12-19 10:47:44

标签: typescript

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

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

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

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

我将如何键入handleGen1?目前,我只能以这种方式看到:

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

有没有更清洁的方式,例如Flowfunction 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;

1 个答案:

答案 0 :(得分:3)

打字稿中没有与*语法等效的内容。通过声明type参数发现的选项是一个不错的选择。请注意,在呼叫站点不必指定额外的参数,打字稿将推断出适当的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

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

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 

必须指定类型参数的缺点是也必须指定类型约束。