Typescript 类型脚本:`{key():type}`vs`{key:()=>;type}`

Typescript 类型脚本:`{key():type}`vs`{key:()=>;type}`,typescript,Typescript,我的一位同事刚刚在一份公关中写下了这句话,我很惊讶它居然能起作用,因为我从未见过它的语法 这两者有什么区别吗 type x = { foo(): void; bar: () => void; } const x: x = { foo: () => { }, bar: () => { } } 仅就类型而言,没有区别: type x = { foo(): void; bar: () => void; } type Foo

我的一位同事刚刚在一份公关中写下了这句话,我很惊讶它居然能起作用,因为我从未见过它的语法

这两者有什么区别吗

type x = {
    foo(): void;
    bar: () => void;
}

const x: x = {
    foo: () => { },
    bar: () => { }
}

仅就类型而言,没有区别:

type x = {
    foo(): void;
    bar: () => void;
}


type Foo = x['foo'];
type Bar = x['bar'];
// both are () => void
一般来说,方法或箭头函数体中的
类型不是方法或箭头函数类型的一部分。

第一个(
foo():void;
)是方法定义,第二个(
条:()=>void;
)是恰好属于函数类型的字段定义(
()=>void;

明显的区别是intelisene中用于代码完成的图标

在大多数情况下,功能上没有区别。对于类,方法分配给原型,而字段通常分配给实例,但这只是一种对象类型,因此函数分配的位置实际上取决于执行实现的对象,而不是类型本身

就类型而言,最大的区别是
strictFunctionTypes
()下的行为。其要点是,方法的行为是双变量的,而字段的行为是反变量的,因此在下面的代码中只有一个是错误的:

type x = {
    foo(x: number | string): void;
    bar: (x: number | string) => void;
}

const x: x = {
    foo: (x: number) => { },// this is fine, methods are bivariant 
    bar: (x: number) => { } // err here, fields are contravariant  
}

据我所知,几乎是一样的。一个区别是
绑定到fat arrow(
=>
)函数中的include对象(请参阅)我不同意函数的方法类型与字段类型之间缺乏差异。当然,void没有区别,因为没有参数,但它们的行为确实不同。这是一个你需要经常注意的无形差异-错误消息中没有指示为什么
foo
可以,而
bar
不在你的答案中。是的,这是一个有趣的打字小惊喜。