打字稿通用类型断言

时间:2019-03-30 13:55:59

标签: typescript typescript-typings typescript-generics

这是我对打字稿的观察总结。

以下是一些代码:

type someTypeEnum = '1';
type someOtherTypeEnum = '2' | '3';
type combinedTypeEnum = someTypeEnum | someOtherTypeEnum;

这是第一种情况:-

function typeAssertion<T extends combinedTypeEnum>(args: T): args is someTypeEnum {
    // The error i get
    // A type predicate's type must be assignable to its parameter's type.
    //  Type '"1"' is not assignable to type 'T'.
    return undefined;
}

我不明白为什么这件事失败了,因为如果我们这样做,我们已经将参数限制为CombinedEnum。

typeAssertion('4')

我们已经收到一条错误消息,指出'4'不是有效的参数,所以为什么args is someTypeEnum被认为是无效的谓词。

这是第二种情况:-

function typeAssertion(args: combinedTypeEnum): args is someTypeEnum {
    return undefined;
}

这似乎很好,但是如果我们这样做:-

function someFunction<T extends combinedTypeEnum>(args: T): T {
    if (typeAssertion(args)) {
        // args here is  'T & "1"' 
        args
    }
    return args
};

为什么我们有T&“ 1”,而不仅仅是“ 1”,所以我们特别断言它是someTypeEnum。

我真的很好奇为什么做出这样的决定。 如果事情以不同的方式完成,看看事情会如何破裂真的很有帮助。

1 个答案:

答案 0 :(得分:1)

extends在具有字符串文字时没有多大意义。为了使说明更容易,让我使用其他类型。考虑以下三个类:

class Animal {}

class Dog extends Animal {}

class Cat extends Animal {}

当我们使用泛型时,实际类型由调用者设置:

function foo<T extends Animal>(arg: T) {}

foo(new Dog()); //T is Dog, equivalent to foo(arg: Dog) {}
foo(new Cat()); //T is Cat, equivalent to foo(arg: Cat) {}

现在您可能已经知道我们要去的地方。我们使用类型谓词:

function foo<T extends Animal>(arg: T): arg is Cat {}

当我们调用foo(new Dog())时,最后一个示例与此等效:

function foo(arg: Dog): arg is Cat {}

当然这是行不通的或没有道理的。

对于第二个示例:变量的类型不变。关键是通过声明一个特定的类型,编译器允许您执行此类型可以完成的任何事情。