我试图确定为什么TypeScript允许您将函数的返回类型重载为类型' any'在实现接口时从更具体的类型。
在我的情况下,我在Angular工作,并注入实现的类。
我的环境:
Visual Studio 2017
Angular Version 1.5.5
TypeScript版本2.1.5
以下代码编译没有任何问题:
export interface IFoo {
thing: (parameter: number) => string;
}
export class BarService implements IFoo {
public thing = (parameter: number): any => {
return { "whatever": parameter };
}
}
angular.module("FooBar").service("barService", BarService);
所以现在当我尝试使用IFoo接口时,我希望从“'”中返回一个字符串。函数调用编译器实际上允许它发生!
export class Whatever {
public foo: IFoo;
public myString: string;
static $inject = ["barService"];
constructor(barService: IFoo) {
this.foo = barService;
this.myString = this.foo.thing(0);
}
}
当返回类型超过类型'任何'时,TypeScript似乎无法编译。因为界面的消费者期望一个强类型的对象。
答案 0 :(得分:3)
这是我放在一起的内容。
来自https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#3.1:
TypeScript中的所有类型都是单个顶级类型的子类型,称为 随便哪种。 any关键字引用此类型。 Any类型是 一种类型,可以表示没有约束的任何JavaScript值。
还有:
Any类型用于表示任何JavaScript值。一个值 任何类型都支持与JavaScript和JavaScript中的值相同的操作 对Any上的操作执行最小静态类型检查 值。具体而言,可以访问任何名称的属性 任何值和任何值都可以作为函数或构造函数调用 任何参数列表。
玩耍:
interface IPerson {
name: string
}
class Person implements IPerson {
name: any;
}
// Error
//class Person2 implements IPerson {
// name: number;
//}
const person: Person = new Person();
person.name = 3;
let x: number = 3;
x = <any>"hello"; // Works!
//x = "hello"; // Error
我们甚至可以在上面的一个简单示例中看到,任何可用于覆盖跟随文档的类型系统。
我的信念是,这种行为是为了允许javascript的无类型(灵活)行为的灵活性。
答案 1 :(得分:2)
我不是使用Typescript的专家,而是基于我对any
:
https://www.typescriptlang.org/docs/handbook/basic-types.html
我们在该页面上发现此评论:
“我们希望选择退出类型检查,让值通过编译时检查。”
所以我猜测编译器何时看到any
,它说“我不会确认这种类型”。因此,这个条件必须足以让编译器认为函数已经正确实现。
我曾经认为any
是“接受任何东西”(确实如此)。但更准确地说,它意味着“假设这是你想要的类型。”,从我所看到的。因此,在这种情况下,为方便起见,编译器假定它是string
,并允许编译时检查通过。
答案 2 :(得分:1)
正如我所看到的,有两个地方可以指望TypeScript编译器失败。 BarService返回any和Whatever类,将thing()函数的返回值赋值给myString。
当您在BarService中返回任何内容时,编译器不会失败,因为在TypeScript中,您可以将any用作任何/所有类型的替代。 TypeScript中的任何类型主要是为了更容易支持旧的JavaScript库或代码。点击此处的任意部分:https://www.typescriptlang.org/docs/handbook/basic-types.html。是的可以而且被滥用。
编译器在你的Whatever类中没有失败,因为在这里你使用的接口事实上确实说thing()函数返回一个字符串。编译Whatever类时,编译器不知道BarService。