我试图了解Typescript提供的类型安全的程度。我遇到了一个我预计会出错的情况,但是Typescript并没有抱怨。
我已经定义了一个带有与某个接口匹配的参数的函数。然后我用一些不匹配的参数调用该函数。这是代码(or in playground):
interface ArgumentInterface {
[key: number]: string
}
interface InvalidArgumentInterface {
[key: string]: number
}
interface InvalidArgumentInterface2 {
foo: number
}
function myFunction(arg: ArgumentInterface) {
// function body
}
let validArgument: ArgumentInterface = {};
validArgument[5] = 'I am a string';
let invalidArgument: InvalidArgumentInterface = {
foo: 42
};
let invalidArgument2: {foo: number} = {
foo: 42
};
let invalidArgument3: InvalidArgumentInterface2 = {
foo: 42
};
let invalidArgument4 = {
foo: 42
};
myFunction(validArgument); // no typescript error, as expected
myFunction(invalidArgument); // typescript error, as expected
myFunction(invalidArgument2); // no typescript error!
myFunction(invalidArgument3); // typescript error, as expected
myFunction(invalidArgument4); // no typescript error!
当我的参数变量显式声明一个不兼容的接口时,我会按预期得到一个Typescript错误。但是当我的参数变量声明一个类型文字(没有接口)或者根本没有声明任何类型时,Typescript根本就没有抱怨,尽管我预计会出错。
我有" noImplicitAny" flag设置为true。
有人可以解释这种行为吗?
答案 0 :(得分:2)
您没有收到错误:
myFunction(invalidArgument2);
myFunction(invalidArgument4);
因为它们的类型是{ foo: number; }
并且它与ArgumentInterface
的定义不矛盾,所以值可以是:
let a = {
1: "one",
2: "two",
foo: 4
}
这里用数字索引的是一个字符串值,但foo索引有一个数字值。
如果ArgumentInterface
是:
interface ArgumentInterface {
[key: number]: string;
[key: string]: string;
}
然后你会得到你所期望的错误。
答案 1 :(得分:1)
这是因为TypeScript uses structural typing(与Ocaml一样)。
invalidArgument2
和invalidArgument4
在结构上与ArgumentInterface
兼容,因此,TypeScript乐意接受它们。