Javascript 结构类型不是duck类型

Javascript 结构类型不是duck类型,javascript,typescript,type-systems,duck-typing,structural-typing,Javascript,Typescript,Type Systems,Duck Typing,Structural Typing,如TypeScript中所述: TypeScript的核心原则之一是类型检查关注值的形状。这有时被称为“duck类型”或“structural subtyping”。在TypeScript中,接口充当命名这些类型的角色 我的理解是,上述核心原则与Duck类型无关,但因为TypeScript是静态类型语言 如中所述:它要求将类型检查推迟到运行时,并通过动态类型或反射来实现。。。对象的适用性取决于某些方法和属性(具有适当的含义)的存在,而不是对象的实际类型 我如何理解TypeScript的上述核心

如TypeScript中所述:

TypeScript的核心原则之一是类型检查关注值的形状。这有时被称为“duck类型”或“structural subtyping”。在TypeScript中,接口充当命名这些类型的角色


我的理解是,上述核心原则与Duck类型无关,但因为TypeScript是静态类型语言

如中所述:它要求将类型检查推迟到运行时,并通过动态类型或反射来实现。。。对象的适用性取决于某些方法和属性(具有适当的含义)的存在,而不是对象的实际类型

我如何理解TypeScript的上述核心原则?

来自维基百科和维基百科

如果它看起来像一只鸭子,像鸭子一样游泳,像鸭子一样呱呱叫,那么它很可能就是一只鸭子

这就是TypeScript接口的工作原理。对象必须看起来像接口,而不是显式地实现它

形成链接到的页面:

interface LabelledValue {
    label: string;
}

function printLabel(labelledObj: LabelledValue) {
    console.log(labelledObj.label);
}

let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);
尽管
myObj
没有显式实现
LabelledValue
接口,但它确实具有相同的结构,因此隐式实现了接口。这是鸭子打字

更新如果将
LabelledValue
接口定义为类,则上述代码不会“编译”。这是结构类型

注意TypeScript没有运行时检查,因为它是“编译”到JavaScript的

interface Duck {
    typing(): void;
}

const porky = {} as Duck;

try {
    porky.typing();
} catch (error) {
    console.log(error); // TypeError: porky.typing is not a function
}

const isDucky = (it: { typing?: () => void }): it is Duck =>
    typeof it.typing === 'function';

const daffy = {
    typing: () => console.log('tappity tap tap')
};

if (isDucky(daffy)) {
    daffy.typing(); // tappity tap tap
}

1)DuckType不要求两个对象具有相同的属性(相同的类型和名称)。Duck类型不处理类型等价性。对于对象,如果您调用的属性(比如方法)存在,则duck类型表示您可以调用该方法。2) 结构类型(至少在TypeScript中)处理两个对象的类型等价性,基于这两个对象中成员的类型和名称。不过,接口略有不同。如果一个对象具有与接口中定义的相同的属性和类型,那么该对象将被接受为实现接口,即使它没有明确定义为接口。如果
LabelledValue
是一个类,那么这将改变一切。而且
myObj
不会通过测试,TypeScript会出错这是一个糟糕的例子,我会说,
让myObj:labelledValue={…}
这样就不会再复杂了,你就不能再调用
printlab()
。这是
接口
关键字的目的之一,用于解决您答案中的JS问题:因此隐式实现接口在我看来是不正确的。
这有时被称为“duck typing”
。。。根据严格的定义,我不认为TypeScript在形式上是一个Duck类型系统,谷歌的快速搜索表明这一说法是正确的。TypeScript并不适合维基百科的文章,因为它根本不是一种运行时语言,它只是一个类型检查器。但是,它当然满足几个标准,包括基本的duck原则以及它编译为JavaScript(一种动态类型语言)的事实。@Aaron类型检查主要关注值具有的形状,与结构类型有关,而不是duck类型。因为我对它的理解是。。。类型兼容性和等价性由类型的实际结构或定义决定。在手册的后面,它说同样的。。。值得指出的是,类型检查器不要求这些属性以任何形式出现,只要求接口所需的属性存在并具有所需的类型。我认为您用于duck类型的定义没有错误,但在术语的使用方式上并不完整,这就是为什么TypeScript有时被称为“duck typing”。@Aaron由于编译时和运行时的类型检查,我看到下面这样的示例。。1)
让myObj:labelledValue={size:10,label:“size 10 Object”}必须进行编译时类型检查,这是在结构类型之后进行的。2) 在
函数printLabel(labelledObj:LabelledValue){..}
中接收的参数对象只能在运行时检查,在运行时没有类型(
函数printLabel(labelledObj){}
),因此显然,在第二种情况下,JS遵循的规则与(duck typing)相同。是的,如果您想说,TS是“编译时duck typing”。