typeScript学习笔记(1)
其实语言学习没什么特别的地方,只是在此处记录一些踩坑点或者值得特别注意的地方
2020/04/08 add ts/public/private/protected
2020/06/20 add tsx
2020/09/18 add tsconfig.json
2020/12/28 add typescript decorator
2021/06/10 add typescript and npm
2021/09/07 add typescript type aliases
一个对初学者比较友好的 doc:什么是 TypeScript
为什么使用typescript
references:
什么是TypeScript,为什么我会用它代替JavaScript?
私以为最重要的一点也在于此:
TypeScript是JavaScript的超集,主要提供可选的静态类型,类和接口。其中一个重要好处是使IDE能够在您键入代码时提供更丰富的环境来发现常见错误。
核心原则
值所具有的shape进行类型检查
TypeScript的核心原则之一是对值所具有的shape进行类型检查。 它有时被称做“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。确切说接口对象类型定义
- 接口属性
interface LabelledValue {
label: string;
}
function printLabel(labelledObj: LabelledValue) {
console.log(labelledObj.label);
}
let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);
LabelledValue接口就好比一个名字,用来描述上面例子里的要求。 它代表了有一个 label属性且类型为string的对象。 需要注意的是,我们在这里并不能像在其它语言里一样,说传给 printLabel的对象实现了这个接口。我们只会去关注值的外形。 只要传入的对象满足上面提到的必要条件,那么它就是被允许的。
还有一点值得提的是,类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以。
syntax
public/private/protected
typescript 访问修饰符 public protected private
typescript中private、public、protected修饰符
1)public声明的属性和方法在类的内部和外部均能访问到。(默认状态下的属性即为public)
2)protected声明的方法和属性只能在类的内部和其子类能访问。
3)private声明的方法和属性只能在其类的内部访问。
decorator
在了解 es6 decorator 方法后即可在 ts 中使用 decorator
类型断言 Type Assertion
值 as 类型
或
<类型>值,这种表示方法在 ts 中可能也会表示一个泛型,即形如以下这个,因此一般尽量使用 as 的方式来避免产生混淆。
function createArray<T>(length: number, value: T): Array<T> {
let result: T[] = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
createArray<string>(3, 'x'); // ['x', 'x', 'x']
将任何一个类型断言为 any
将一个变量断言为 any 可以说是解决 TypeScript 中类型问题的最后一个手段。
它极有可能掩盖了真正的类型错误,所以如果不是非常确定,就不要使用 as any。
总之,一方面不能滥用 as any,另一方面也不要完全否定它的作用,我们需要在类型的严格性和开发的便利性之间掌握平衡(这也是 TypeScript 的设计理念之一),才能发挥出 TypeScript 最大的价值。
Type aliases
参考 type-aliases
通常我们在直接书写
.d.ts
文件时往往需要使用到 type aliases,甚至于“支持高级类型的静态类型系统”(生成类型的类型,除了可以传泛型参数外还可以支持分支、递归、取属性等操作,可以通过复杂的逻辑生成类型)
比如:
// 其中 Item 是重复的目标, n 是个数,然后第三个参数 Tuple 用来存储结果
type RepeatN<Item, N extends number, Tuple extends any[] = []> = Tuple['length'] extends N ? Tuple : RepeatN<Item, N, [...Tuple, Item]>;
// 上述代码实际上做的就是如下
function repeactN(item, n) {
const res = [];
for (let i = 0; i< n; i++) {
res[i] = item;
}
return res;
}
那么这时候就有一个问题,type 和 interface 有什么区别呢?
Differences Between Type Aliases and Interfaces
TypeScript: Interfaces vs Types
实用类型 utility types
Partial: 构造一个表示给定类型的所有子集的类型。
Record<Keys, Type>: 构造一个对象类型,其属性键为键,属性值为类型。此实用程序可用于将一个类型的属性映射到另一个类型。
configuration
what’s tsconfig.json
- 是什么?
- TypeScript 使用 tsconfig.json 文件作为其配置文件,当一个目录中存在 tsconfig.json 文件,则认为该目录为 TypeScript 项目的根目录。
通常 tsconfig.json 文件主要包含两部分内容:指定待编译文件和定义编译选项。
- 为什么用?
- 通常我们可以使用 tsc 命令来编译少量 TypeScript 文件:
/*
参数介绍:
--outFile // 编译后生成的文件名称
--target // 指定ECMAScript目标版本
--module // 指定生成哪个模块系统代码
index.ts // 源文件
*/
$ tsc --outFile leo.js --target es3 --module amd index.ts
但如果实际开发的项目,很少是只有单个文件,当我们需要编译整个项目时,就可以使用 tsconfig.json 文件,将需要使用到的配置都写进 tsconfig.json 文件,这样就不用每次编译都手动输入配置,另外也方便团队协作开发。
项目中的使用
ts 逐渐替代 js 成为我的项目开发中的必须语言,此处记录下使用过程中的一些心得。
- ts 开发往往需要 声明文件,比如 @types/jest , 而这类声明文件的由来可以参考 https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html,以及TypeScript typings in npm @types org packages