与 TypeScript 相关的一些记录

栏目: IT技术 · 发布时间: 4年前

内容简介:本文记录两件事,一个是关于 typing 的一些名词释义,另一个便是结合 TypeScript 给出一些示例用于解释这门语言的能力。说到 typing 分类,常见的维度分为以下几种:而以上说到的最后一个分类也被用于引出 TypeScript 所采用的类型系统——结构类型系统。
A type system specifies the type rules of a programming language independently of particular typechecking algorithms. This is analogous to describing the syntax of a programming language by a formal grammar, independently of particular parsing algorithms. —— Type Systems

本文记录两件事,一个是关于 typing 的一些名词释义,另一个便是结合 TypeScript 给出一些示例用于解释这门语言的能力。

1. 关于 typing 的一些名词释义

说到 typing 分类,常见的维度分为以下几种:

  • Static (expressions have types) vs. dynamic (values have types) - 静态类型和动态类型,区分的关键点为编译期或运行期确定类型:静态类型在编译期确定,动态类型在运行期确定。
  • Strong (values cannot be coerced to other types without a cast) vs. weak (the runtime performs a variety of coercions for convenience) - 强类型和弱类型,区分的关键点为运行时是否自动转换到与实际类型不符的类型:强类型要求手工类型转换,弱类型自动转换。
  • Latent (no type declarations) vs. manifest (type declarations) - 隐式类型和显式类型,区分的关键点为是否要在源码中声明类型:隐式类型不需要,显式类型需要。
  • Nominal (subtyping relations are declared explicitly) vs. structural (subtyping relations are inferred from the operations available on types) - 标明类型和结构类型,区分的关键点为类型判定是根据标称还是根据内容:标明类型根据标称,结构类型根据内容。

而以上说到的最后一个分类也被用于引出 TypeScript 所采用的类型系统——结构类型系统。

  • 结构类型系统 / Structure Type System,可以简单理解成“任两个以相同结构所描述的值的类型都是等价的”。
  • 标明类型系统 / Nominal Type System,则可以简单理解成“没有两个独特的语法构成的类型表达式表示同一类型,(即类型若要相等,就必须具有相同的“名字”)”。

其他还有一些名词:

  • 鸭子类型 / Duck Typing - 在程序设计中是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由”当前方法和属性的集合”决定。在与结构类型系统的对比上,鸭子类型和结构类型相似但与之不同。结构类型由类型的结构决定类型的兼容性和等价性,而鸭子类型只由结构中在运行时所访问的部分决定类型的兼容性。
  • 泛型 / Generic - 泛型程序设计(generic programming)是程序设计语言的一种风格或范式。泛型允许 程序员 在强类型程序设计语言中编写代码时使用一些以后才指定的类型,在实例化时作为参数指明这些类型。

关于类型系统有一本“小书”,也就几十页,但个人看起来还相当吃力,感兴趣可以移步

Cardelli, Luca. “ Type systems .” ACM Computing Surveys 28.1 (1996): 263-264.

2. 关于 TypeScript 系统性入门的一些标注

2.1TypeScript 采用结构类型系统(Structure Type System)

TypeScript 和 C# 有着颇深的渊源,他们都是在微软大神 Anders Hejlsberg 的领导之下产生的编程语言,两者在诸多设计细节方面十分相似。然而,一个非常重要的不同之处在于,C# 采用的是 Nominal Type System(标明类型系统),TypeScript 考虑到 JavaScript 本身的灵活特性,采用的是 Structural Type System。

关于标明类型系统和结构类型系统的区别,可以看这个例子。这里是一段 C# 代码:

// 示例 from https://zhuanlan.zhihu.com/p/64446259

public class Foo  
{
    public string Name { get; set; }
    public int Id { get; set;}
}

public class Bar  
{
    public string Name { get; set; }
    public int Id { get; set; }
}

Foo foo = new Foo(); // Okay.
Bar bar = new Foo(); // Error!!!

FooBar 两个类的内部定义完全一致,但是当将 Foo 实例赋值给 Bar 类型的变量时编译器报错,说明两者的类型并不一致。标明类型系统比较的是类型本身,具备非常强的一致性要求。

TypeScript 则不太一样:

// 示例 from https://zhuanlan.zhihu.com/p/64446259

class Foo {
  method(input: string): number { ... }
}

class Bar {
  method(input: string): number { ... }
}

const foo: Foo = new Foo(); // Okay.
const bar: Bar = new Foo(); // Okay.

2.2TypeScript 和 JavaScript 广泛应用鸭子类型相似,只检查类型定义的约束条件

下面这个例子比较能够说明这一类型系统的灵活性:

// 示例 from https://zhuanlan.zhihu.com/p/64446259

type Point = {
  x: number;
  y: number;
};

function plot(point: Point) {
  // ...
}

plot({ x: 10, y: 25 }); // Okay.
plot({ x: 8, y: 13, name: 'foo' }); // Extra fields Okay. Need enable `suppressExcessPropertyError`

2.3用 TypeScript 进行类型编程

一个典型便是泛型。软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。

正常情况,我们会这样定义一个函数:

function identity(arg: number): number {
    return arg;
}

若是 arg 改变类型,那么我们的函数可能又要改写成这样:

function identity(arg: string): string {
    return arg;
}

因此,我们需要一种方法使返回值的类型与传入参数的类型是相同的。 类型变量,是一种特殊的变量,只用于表示类型而不是值,如上示例可以写成:

function identity<T>(arg: T): T {
    return arg;
}

2.4TypeScript 提供一些 工具 类型来帮助常见的类型转换

这里举例一个有意思的类型 NonNullable,这里粘同事写的一个例子来说明:

function isNotNil<T>(x: T): x is NonNullable<T> {
  return x != null;
}

const type_guard_demo_1 = [1, 2, '', undefined, null].filter(isNotNil);

假设我们在这里不明确写上 isNotNil 的返回类型,那么 TypeScript 给你的推断结果或许就是,至少 TypeScript playground 上还是这样:

const type_guard_demo_1: (string | number | null | undefined)[]

而对返回结果加上 NonNullable 声明,便可以得到你想要的结果:

const type_guard_demo_1: (string | number)[]

NonNullable<T> 做的事情便是从类型T中剔除 null 和 undefined,然后构造一个类型。而得益于 TypeScript 本身就是用 TypeScript 开发的,你可以很容易看到 NonNullable 的实现:

/**
 * Exclude null and undefined from T
 */
type NonNullable<T> = T extends null | undefined ? never : T;

在你觉得类型不够用的时候,你还可以通过 条件类型(Conditional Type) 来创造更多的自定义工具类型。

后记

以上,是对这两部分内容的一些笔记,但这不适用于针对 TypeScript 的整体入门,因为相关内容还是欠缺太少,相关内容应该会另起篇幅书写。另外,如果你想尝试写些 TypeScript 代码, TypeScript Playground 会是一个比较不错的选择。

参考的资料与可以进一步阅读的资料包含在如下链接中:


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

点石成金

点石成金

[美] 克鲁格 (Steve Krug) / 蒋芳 / 机械工业出版社 / 2015-1-1 / CNY 59.00

《点石成金:访客至上的Web和移动可用性设计秘笈(原书第3版)》是一本关于Web设计原则而不是Web设计技术的书。《点石成金:访客至上的Web和移动可用性设计秘笈(原书第3版)》作者是Web设计专家,具有丰富的实践经验。他用幽默的语言为你揭示Web设计中重要但却容易被忽视的问题,只需几个小时,你便能对照书中讲授的设计原则找到网站设计的症结所在,令你的网站焕然一新。一起来看看 《点石成金》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具