- 第1节:TypeScript 快速入门
- 第2节:TypeScript 2.0介绍
- 第3节:TypeScript 2.1介绍
- 第4节:TypeScript 3.1介绍
- 第5节:TypeScript 基础类型
- 第6节:TypeScript 变量声明
- 第7节:TypeScript 接口
- 第8节:TypeScript 类
- 第9节:TypeScript 函数
- 第10节:TypeScript 泛型
- 第11节:TypeScript 枚举
- 第12节:TypeScript 类型推论
- 第13节:TypeScript 类型兼容性
- 第14节:TypeScript 高级类型
- 第15节:TypeScript Symbols
- 第16节:TypeScript 迭代器和生成器
- 第17节:TypeScript 模块
- 第18节:TypeScript 命名空间
- 第19节:TypeScript 命名空间和模块
- 第20节:TypeScript 模块解析
- 第21节:TypeScript 声明合并
- 第22节:TypeScript JSX
- 第23节:TypeScript 装饰器
- 第24节:TypeScript Mixins
- 第25节:TypeScript 三斜线指令
- 第26节:TypeScript 声明文件结构
- 第27节:TypeScript 声明文件举例
- 第28节:TypeScript 声明文件规范
- 第29节:TypeScript 声明文件原理
- 第30节:TypeScript 声明文件模板
- 第31节:TypeScript 声明文件发布
- 第32节:TypeScript 声明文件使用
- 第33节:TypeScript tsconfig.json
- 第34节:TypeScript 编译选项
- 第35节:TypeScript MSBuild编译选项
- 第36节:TypeScript 构建工具整合
- 第37节:TypeScript 每日构建
TypeScript 3.1介绍
元组和数组上的映射类型
在 TypeScript 3.1 中,元组和数组上的映射对象类型现在产生新的元组/数组,而不是创建一个新的类型,其中的成员,比如push()
,pop()
和length
将被转换。例如:
type MapToPromise<T> = { [K in keyof T]: Promise<T[K]> };
type Coordinate = [number, number]
type PromiseCoordinate = MapToPromise<Coordinate>; // [Promise<number>, Promise<number>]
MapToPromise
使用一种类型T
,当该类型是一个元组,例如Coordinate
,它只转换数字属性。在[number, number]
中,有两个数字命名的属性:0
和1
。当给出这样的元组时,MapToPromise
将创建一个新的元组,其中0
和1
属性是原始类型的Promise
s。因此,结果类型PromiseCoordinate
最终会得到类型[Promise<number>, Promise<number>]
。
函数的属性声明
TypeScript 3.1 能够在函数声明和const
-declared functons 上定义属性,只需在同一范围内分配这些函数的属性即可。这允许我们编写规范的JavaScript代码而不求助于namespace
。例如:
function readImage(path: string, callback: (err: any, image: Image) => void) {
// ...
}
readImage.sync = (path: string) => {
const contents = fs.readFileSync(path);
return decodeImageSync(contents);
}
在这里,我们有一个以非阻塞异步方式读取图像的readImage
函数。除了readImage
外,我们在readImage
提供了一个方便的函数,名为readImage.sync
。
虽然ECMAScript导出通常是提供此功能的更好方式,但这种新的支持允许使用此样式编写的代码“仅仅工作” TypeScript。另外,这种属性声明方法让我们在React无状态功能组件(SFCs)上表达常用模式,例如defaultProps
和propTypes
。
export const FooComponent => ({ name }) => (
<div>Hello! I am {name}</div>
);
FooComponent.defaultProps = {
name: "(anonymous)",
};
更具体地说,同态映射类型类似于上面的形式。
使用 typesVersions 进行版本选择
来自社区的反馈以及相关的经验告诉我们,利用最新的TypeScript功能同时也容纳旧版本的用户是很困难的。TypeScript引入了一项名为typesVersions
的新功能,以帮助满足这些方案。
在 TypeScript 3.1 中使用节点模块分辨率时,当 TypeScript 破解打开package.json
文件以确定需要读取哪些文件时,它首先会查看名为typesVersions
的新字段。带有typesVersions
字段的package.json
可能如下所示:
{
"name": "package-name",
"version": "1.0",
"types": "./index.d.ts",
"typesVersions": {
">=3.1": { "*": ["ts3.1/*"] }
}
}
这package.json
告诉TypeScript检查当前版本的TypeScript是否正在运行。如果它是3.1或更高版本,它会计算出您相对于包导入的路径,并从包的ts3.1
文件夹中读取。这就是{ "*": ["ts3.1/*"] }
表达的意思 - 如果你现在熟悉路径映射,它的工作原理就是这样的。
因此,在上面的示例中,如果我们从"package-name"
中导入,在TypeScript 3.1中运行时,我们将尝试从[...]/node_modules/package-name/ts3.1/index.d.ts
(和其他相关路径)解析。如果我们从package-name/foo
导入,我们将尝试寻找[...]/node_modules/package-name/ts3.1/foo.d.ts
和[...]/node_modules/package-name/ts3.1/foo/index.d.ts
。
如果我们在这个例子中没有在 TypeScript 3.1 中运行怎么办?好吧,如果typesVersions
中没有匹配的字段,TypeScript会回退到types
字段,因此 TypeScript 3.0 及更早版本将被重定向到[...]/node_modules/package-name/index.d.ts
。
匹配行为
TypeScript决定编译器和语言版本是否匹配的方式是使用Node的semver范围。
多个字段
typesVersions
可以支持多个字段,其中每个字段名称由要匹配的范围指定。
{
"name": "package-name",
"version": "1.0",
"types": "./index.d.ts",
"typesVersions": {
">=3.2": { "*": ["ts3.2/*"] },
">=3.1": { "*": ["ts3.1/*"] }
}
}
由于范围可能会重叠,因此确定应用哪种重定向是特定于订单的。这意味着在上面的示例中,即使>=3.2
和>=3.1
匹配器都支持 TypeScript 3.2 及更高版本,反转顺序也可能有不同的行为,因此上述示例将不等同于以下示例:
{
"name": "package-name",
"version": "1.0",
"types": "./index.d.ts",
"typesVersions": {
// NOTE: this doesn't work!
">=3.1": { "*": ["ts3.1/*"] },
">=3.2": { "*": ["ts3.2/*"] }
}
}