打字稿能否在通用类型中缩小联合类型?

时间:2019-01-22 15:49:36

标签: typescript

可以出于以下目的编译代码:

type Tick = Date | number;

type Unary<T, R> = (_: T) => R;

function formatter<T extends Tick>(tick: T): Unary<T, string> {
    if (tick instanceof Date) {
        return (date: Date) => date.toUTCString();
    }
    return (int: number) => int.toFixed();
}

playground link

我的想法是,如果TDatetickDate,返回类型为Unary<Date, string>,但是Typescript尝试将其与{{ 1}}。这是因为Unary<T, string>T extends Tick联合更广泛吗?如果是这样,我可以限制这种通用吗?

1 个答案:

答案 0 :(得分:3)

不要认为您可以缩小泛型类型的参数的类型。任何类型的gard仍将在其中保留type参数,因为编译器假定type参数可以是任何派生类型,因此无法消除不确定的信息。

此外,您试图基于对参数的检查来缩小所有类型参数的出现范围(即返回类型的出现范围),这绝对是不可能的。类型防护在特定变量上起作用,而不是在整个类型上起作用。

一种选择是使用单独的实现签名:

type Tick = Date | number;

type Unary<T, R> = (_: T) => R;

function formatter<T extends Tick>(tick: T): Unary<T, string> 
function formatter(tick: Tick): Unary<Date, string> | Unary<number, string> {
    if (tick instanceof Date) {
        return (date: Date) => date.toUTCString();
    }
    return (int: number) => int.toFixed();
}