Typescript函数接受无效参数且没有错误

时间:2017-01-31 11:24:24

标签: typescript

我试图了解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。

有人可以解释这种行为吗?

2 个答案:

答案 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一样)。

invalidArgument2invalidArgument4在结构上与ArgumentInterface兼容,因此,TypeScript乐意接受它们。