详细解释一个奇怪的打字行为

行为方式

行为方式

作者|马修·米勒|我最近读了Asana的博客,看到一篇关于打字稿奇怪行为的文章。文章中提到的第一个引起了我的兴趣。尽管看起来不一致,但这种类型的系统实际上完全符合逻辑。

本文以接口狗和函数打印狗为例:

接口狗{

繁殖:string

}

函数打印狗(狗:狗){

console.log("狗:"+狗.繁殖)

}

这段代码模拟了一种流行的打字风格到目前为止似乎没有问题,但是这篇文章引入了一个看似“不一致”的情况。尽管您可以在将包含繁殖属性的对象传递给函数之前将其赋给变量,但不能将对象直接传递给函数。

const ginger = {

品种:“Airedale”,

年龄:3

};

printDog(生姜);//作品

printDog({

品种:“Airedale”,

年龄:3

});///失败

这是为什么?TypeScript检查对象中的附加属性并发现错误,但是为什么只有当对象直接传递给函数时才会出现问题?本文

指出TypeScirpt是一种“结构化类型语言”,即类型检查是基于对象的结构,而不是基于其继承关系但是,该规则有一个例外,即在开发显式指定的变量类型时此外,TypeScript函数的参数是协变的,这意味着它可以接受任何子类型。在结构化类型语言中,向现有类型添加属性等同于扩展该类型

那么,为什么会出现这个错误呢?如果它允许传递指定类型的任何子类型,那么为什么有时会出现错误呢?

要回答这个问题,您需要回到我前面提到的系统类型。当创建一个变量并将其传递给一个函数时,该变量推断出一个类型当在函数中创建对象时,我们明确地告诉类型脚本变量是狗类型的创建变量时,检查类型是否包含额外的属性,但在调用函数时不检查,因为函数调用是协变的这种“不一致”与函数调用无关,只要指定的类型在创建对象时产生相同的行为:

cons inger:dog = {

bred:" a iredale ",

age:3

};

此代码将生成与函数类型相同的错误,因为年龄不是Dog类型的属性

虽然类似的问题经常困扰着TypeScript开发人员,但是对于类型系统的任何行为通常都有合理的解释。如果没有,那么您应该向微软报告错误

原文:https://Matthew miller . dev/blog/demosthetifying-typescript-quirk/

本文为CSDN译文,请注明转载来源。

【结束】

大家都在看

相关专题