为什么 TypeScript 在实现泛型接口时无法推断函数参数的类型?

2024-03-25

我正在 Visual Studio 2015 中编写 TypeScript,安装了 2.3.3.0 版本的语言服务扩展。我有noImplicitAny参数设置为true在我的项目中tsconfig.json.

给出这个简单的示例代码:

interface ITransformer<TInput, TOutput> {
    transform(input: TInput): TOutput;
}

class Input {
    name: string;
}

class Output {
    name: string;

    constructor(name: string) {
        this.name = name;
    }
}

class Test {
    name: string;
}

class Transformer implements ITransformer<Input, Output> {
    transform = (input) => new Output(input.name);
}

TS 编译器给我一个错误:TS7006: Parameter 'input' implicitly has an 'any' type:

现在,我可以通过向input范围:

class Transformer implements ITransformer<Input, Output> {
    transform = (input: Input) => new Output(input.name);
}

但我的问题是,为什么我必须这样做?在我看来,该参数的类型应该从TInput在接口的实现中(在本例中,Input).

更令人担忧的是,我可以愉快地这样做:

class Transformer implements ITransformer<Input, Output> {
    transform = (input: Test) => new Test();
}

它接受并返回未引用的完全不同的类型either类型参数,编译器似乎没有问题......

对于具有 C# 背景的人来说,这似乎是错误的。我缺少什么?


当实施ITransformer您可以覆盖的接口transform具有不同的签名,例如:

class Transformer implements ITransformer<Input, Output> {
    transform(input: string): Output;
    transform(input: number): Output;
    transform(input: Input): Output;
    transform(input: any): Output {
        // ...
    }
}

您不必只在接口中实现签名。因此,您必须隐式编写类型:

transform = (input: Input) => new Output(input.name);

至于为什么会这样:

transform = (input: Test) => new Test();

那是因为TypeScript 基于结构子类型 https://www.typescriptlang.org/docs/handbook/type-compatibility.html并且这两种类型具有相同的结构({ name: string })。尝试仅向其中一个属性添加另一个属性,您将收到错误消息。

我想指出的最后一件事是,定义类方法的方式实际上不会创建方法,而只是创建具有函数类型的成员:

class Test {
    method1() { }

    method2 = () => {}
}

仅此method1确实是一种方法,同时method2只是在构造函数中分配的属性,它不会成为原型的一部分,并且如果扩展类,您将无法覆盖它。

这是此代码的编译版本:

var Test = (function () {
    function Test() {
        this.method2 = function () { };
    }
    Test.prototype.method1 = function () { };
    return Test;
}());

这种方法很好并且正在使用,但请注意。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 TypeScript 在实现泛型接口时无法推断函数参数的类型? 的相关文章

随机推荐