从两个角度看 Typescript 中的类型是什么?

简介: 以下三个问题对于理解类型是如何工作的非常重要,需要从这两个角度中的每一个角度来回答。

640 (5).png

0. 作者以及原文介绍


作者是 Dr. Axel Rauschmayer,号称”德国阮一峰“,本文原文来自于他的博客:https://2ality.com/2020/02/understanding-types-typescript.html,不熟悉他的可以关注一下他的博客。


以下是原文:


1. 每个角度都从这三个问题来解释


以下三个问题对于理解类型是如何工作的非常重要,需要从这两个角度中的每一个角度来回答。


  1. myVariable 的类型 MyType 意味着什么?


let myVariable: MyType = /*...*/;


  1. Sourcetype 可以分配给 TargetType 吗?


let source: SourceType = /*...*/;
let target: TargetType = source;


  1. TypeUnion 是如何从Type1Type2Type3 衍生而来的?

type TypeUnion = Type1 | Type2 | Type3;


2. 角度 1:类型是一组值


从这个角度来看,类型是一组值:


  1. 如果 myVariable 具有 MyType 类型,这意味着可以分配给 myVariable 的所有值都必须是集合 MyType 的元素。


  1. 如果 Sourcetype 可以分配给 TargetType,那么 SourcetypeTargetType 的子集。因此,TargetType 也允许SourceType 所允许的所有值。


  1. 类型 Type1Type2Type3的联合类型是定义它们的集合在集合论中的并集。


3. 角度 2:类型兼容关系


从这个角度来看,我们不关心值以及它们在执行代码时如何流动。相反,我们采取了一种更为静态的观点:


  • 源代码有个位置,每个位置都有一个静态类型。在支持 Typescript 的编辑器中,如果我们将鼠标悬停在某个位置的上方,就可以看到该位置的静态类型。


  • 当源位置通过赋值、函数调用等方式连接到目标位置时,源位置的类型必须与目标位置的类型兼容。Typescript 规范通过所谓的类型关系定义类型的兼容性。


  • 类型关系分配兼容性定义了源类型 S 何时可以分配给目标类型 T:


  • ST 都是一样的类型


  • S 或者 T 是 any 类型。


  • 等等


让我们考虑以下问题:


  1. 如果 myVariable 的静态类型可以分配给 MyType ,那么 myVariable 就具有类型 MyType


  1. 如果 SourceTypeTargetType 是互相兼容的,那么SourceType可以分配给 TargetType


  1. 联合类型的工作方式是通过类型关系成员定义的。

类型系统一个有趣的特点是,同一个变量在不同的位置可以有不同的静态类型:


const arr = [];
// %inferred-type: any[]
arr;
arr.push(123);
// %inferred-type: number[]
arr;
arr.push('abc');
// %inferred-type: (string | number)[]
arr;


4. 标准类型系统和结构类型系统


静态类型系统的职责之一是确定两个静态类型是否兼容:


  • 实际参数的静态类型 U(例如,通过函数调用提供)


  • 对应形式参数的静态类型 T(指定为函数定义的一部分)


这通常意味着要检查 U 是否是 T 的子类型。这种检查的两种方法(大致)是:


  • 在标准类型中,如果两个静态类型具有相同的标识(“名称”) ,则它们是相等的。一种类型是另一种类型的子类型,它们的子类型关系是显式声明的。


具有标准类型的语言有 c++Javac#SwiftRust


  • 在结构类型系统中,如果两个静态类型具有相同的结构(如果它们的部分具有相同的名称和相同的类型) ,则它们是相等的。如果 U 包含 T 的所有部分(可能还包括其他部分) ,并且 U 的每个部分都包含 T 的相应部分的子类型,那么一种类型 U 就是另一种类型 T 的子类型。


具有结构类型的语言有 ocaml/reasonmlHaskellTypeScript


下面的代码在标准类型系统中产生类型错误(第 A 行) ,但在 Typescript 的结构类型系统中是合法的,因为类 A 和类 B 具有相同的结构:


class A {
  name = 'A';
}
class B {
  name = 'B';
}
const someVariable: A = new B(); // (A)


Typescript 的接口在结构上也能工作——它们不需要实现来匹配:


interface Point {
  x: number;
  y: number;
}
const point: Point = {x: 1, y: 2}; // OK


5. 进一步阅读


  • Chapter “Type Compatibility” in the TypeScript Handbook[1]


  • Section “TypeRelationships” in the TypeScript Specification[2]


如果翻译得不对的地方希望您可以帮忙指出来。


参考资料


[1]

Chapter “Type Compatibility” in the TypeScript Handbook: https://www.typescriptlang.org/docs/handbook/type-compatibility.html


[2]

Section “TypeRelationships” in the TypeScript Specification: https://github.com/microsoft/TypeScript/blob/master/doc/spec.md#311-type-relationships

目录
相关文章
|
15天前
|
存储 安全 JavaScript
TypeScript-内置应用程序类型-Recode
通过使用 `Record` 类型,开发者可以显著提升代码的安全性和可维护性。无论是配置对象、字典结构还是动态表单,`Record` 类型都提供了一个简洁、类型安全的解决方案。
187 82
|
3月前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
66 2
|
3月前
|
设计模式 JavaScript 安全
TypeScript性能优化及代码质量提升的重要性、方法与策略,包括合理使用类型注解、减少类型断言、优化模块导入导出、遵循编码规范、加强代码注释等
本文深入探讨了TypeScript性能优化及代码质量提升的重要性、方法与策略,包括合理使用类型注解、减少类型断言、优化模块导入导出、遵循编码规范、加强代码注释等,旨在帮助开发者在保证代码质量的同时,实现高效的性能优化,提升用户体验和项目稳定性。
71 6
|
3月前
|
JavaScript 安全 前端开发
TypeScript类型声明:基础与进阶
通过本文的介绍,我们详细探讨了TypeScript的基础与进阶类型声明。从基本数据类型到复杂的泛型和高级类型,TypeScript提供了丰富的工具来确保代码的类型安全和可维护性。掌握这些类型声明能够帮助开发者编写更加健壮和高效的代码,提高开发效率和代码质量。希望本文能为您在使用TypeScript时提供实用的参考和指导。
63 2
|
3月前
|
JavaScript 前端开发 安全
TypeScript进阶:类型系统与高级类型的应用
【10月更文挑战第25天】TypeScript作为JavaScript的超集,其类型系统是其核心特性之一。本文通过代码示例介绍了TypeScript的基本数据类型、联合类型、交叉类型、泛型和条件类型等高级类型的应用。这些特性不仅提高了代码的可读性和可维护性,还帮助开发者构建更健壮的应用程序。
48 0
|
3月前
|
JavaScript 开发者
在 Babel 插件中使用 TypeScript 类型
【10月更文挑战第23天】可以在 Babel 插件中更有效地使用 TypeScript 类型,提高插件的开发效率和质量,减少潜在的类型错误。同时,也有助于提升代码的可理解性和可维护性,使插件的功能更易于扩展和升级。
|
4月前
|
JavaScript 前端开发
TypeScript【类型别名、泛型】超简洁教程!再也不用看臭又长的TypeScript文档了!
【10月更文挑战第11天】TypeScript【类型别名、泛型】超简洁教程!再也不用看臭又长的TypeScript文档了!
|
4月前
|
JavaScript 前端开发 安全
TypeScript【基础类型】超简洁教程!再也不用看臭又长的TypeScript文档了!
【10月更文挑战第9天】TypeScript【基础类型】超简洁教程!再也不用看臭又长的TypeScript文档了!
|
4月前
|
移动开发 JavaScript 前端开发
TypeScript:数组类型&函数使用&内置对象
本文介绍了 TypeScript 中的数组类型、对象数组、二维数组、函数、函数重载、内置对象等概念,并通过代码示例详细展示了它们的使用方法。还提供了一个使用 HTML5 Canvas 实现的下雨效果的小案例。
|
4月前
|
JavaScript 前端开发 开发者
深入理解TypeScript:类型系统与最佳实践
【10月更文挑战第8天】深入理解TypeScript:类型系统与最佳实践