在混合接口中键入检查

时间:2018-03-09 06:15:18

标签: typescript typescript2.0

这是TypeScript手册here -

中提到的一个例子
  

混合类型

     

正如我们前面提到的,接口可以描述丰富的类型   存在于现实世界的JavaScript中。因为JavaScript的动态和   灵活的性质,你偶尔会遇到一个有效的物体   作为上述某些类型的组合。

     

一个这样的例子是一个同时充当函数和对象的对象   对象,具有其他属性:

interface Counter {
    (start: number): string;
    interval: number;
    reset(): void;
}

function getCounter(): Counter {
    let counter = <Counter>function (start: number) { };
    counter.interval = 123;
    counter.reset = function () { };
    return counter;
}

let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;

如果我将函数getCounter中的类型转换行修改为此,编译器仍会将其验证为好。

let counter = <Counter>{ };

但是如果你运行已编译的JavaScript,它会给出错误,因为计数器现在不是一个真正的函数而是一个对象。

问题 - TypeScript编译器是否应该在这种情况下给出任何错误,或者它是否正确,因为函数是Object的子类型?

编辑器的链接是here

2 个答案:

答案 0 :(得分:1)

< >运算符是强制类型断言/强制转换。您告诉编译器忽略它所知道的关于该对象的所有内容,并假设它是在尖括号内指定的类型。所以从Typescript编译器方面来说一切都很好。这意味着从使用方面来说,如果您完全确定类型是正确的,那么您应该只回到那些演员阵容。

类型断言部分中的更多信息:https://www.typescriptlang.org/docs/handbook/basic-types.html

答案 1 :(得分:1)

类型断言用于告诉编译器忽略它所知道的类型,而不是你告诉它的类型。如果您对断言错了,那么编译器就无法向您发出警告。当你需要这样做时,在Typescript中肯定有类型,但是如果你能找到一种类型安全的方法来做同等的事情,那就更好了。在这种情况下,您可以使用Object.assign

function getCounter(): Counter {
    let counter = Object.assign(function (start: number) {  return ""}, {
        interval: 123,
        reset: function () { }
    });
    return counter;
}