打字稿约束未验证

时间:2020-06-10 22:09:48

标签: typescript typescript-generics

为什么我的TS linter和编译器都不会在这里的test方法中抱怨大屠杀的类型?看来item: T约束根本没有得到验证。

在TS 3.8.3和旧版3.2.2上进行了测试:

export class Foo {}

export class Bar {}

export class FooBar {
    test() {
        const thisIsNotABar: Bar = this.echo<Bar>(new Foo());
    }

    echo<T>(item: T): T {
        return item;
    }
}

2 个答案:

答案 0 :(得分:2)

这是因为Foo和Bar是兼容的(它们的定义是相同的)。尝试将一个属性添加到另一个属性中,而TypeScript应该会给您一个错误:

export class Foo { a: any }

export class Bar { b: any }

export class FooBar {
    test() {
        const thisIsNotABar: Bar = this.echo<Bar>(new Foo());
    }

    echo<T>(item: T): T {
        return item;
    }
}

给出错误:

类型'Foo'的参数不能分配给'Bar'类型的参数。 属性“ b”在“ Foo”类型中丢失,但在“ Bar”类型中是必需的。

答案 1 :(得分:2)

啊,欢迎来到TypeScript的structural type system。在TypeScript中,如果两个类型具有相同的 shape 结构,则它们是相同的。它不依赖于类型的名称声明,例如在nominal type systems中,您可能会更习惯其他语言。

因此,即使您的FooBar具有不同的名称和不同的声明,它们的形状仍相同。 em>和结构;即empty object type的值。因此,在TypeScript中,FooBar是完全相同的类型。

如果您想将FooBar视为不同,则应添加结构的某些不兼容性,例如赋予它们不同的属性:

export class Foo {
    foo = ""
}

export class Bar {
    bar = ""
}

如果这样做,则应该发生您期望的错误:

    const thisIsNotABar: Bar = this.echo<Bar>(new Foo()); // error!
    // Foo is not assignable to Bar

好的,希望能有所帮助;祝你好运!

Playground link to code