混合接口中的类型检查

Type Checking in Hybrid Interfaces

这是 TypeScript 手册中提到的示例 here -

Hybrid Types

As we mentioned earlier, interfaces can describe the rich types present in real world JavaScript. Because of JavaScript’s dynamic and flexible nature, you may occasionally encounter an object that works as a combination of some of the types described above.

One such example is an object that acts as both a function and an object, with additional properties:

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,它会给出错误,因为 counter 现在不是一个真正的函数而是一个对象。

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

给编辑的link是here

< >运算符是强制类型assertion/cast。你告诉编译器忽略它所知道的关于对象的一切,并假设它是尖括号内指定的类型。因此,从 Typescript 编译器方面来看,一切都很好。这意味着从使用方面来说,如果您绝对确定类型是正确的,您应该只回退到那些类型转换。

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

类型断言用于告诉编译器忽略它知道的类型,支持您告诉它的类型。如果您做出的断言是错误的,编译器将无法警告您。当您需要执行此操作时,Typescript 中肯定有类型,但如果您能找到一种类型安全的方法来执行等效操作,那会更好。在这种情况下,您可以使用 Object.assign:

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