1.环境搭建
1)安装ts
1 2 3 4 5 6 7 8 9 10
| npm install -g typeScript
mkdir ts-study && cd ts-study
mkdir src && touch src/index.ts
npm init
tsc --init (初始化配置,生成tsconfig.json配置ts文件)
|
package.json中加入我们的script命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| { "name": "ts-study", "version": "1.0.0", "description": "", "main": "src/index.ts", "scripts": { "build": "tsc", "build:w": "tsc -w" }, "author": "", "license": "ISC", "devDependencies": { "TypeScript ": "^3.6.4" } }
|
tsconfig.json配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| { "compilerOptions": { "target": "es5", "module": "commonjs", "moduleResolution": "node", "experimentalDecorators": true, "allowSyntheticDefaultImports": true, "sourceMap": true, "strict": true, "noImplicitAny": true, "alwaysStrict": true, "declaration": true, "removeComments": true, "noImplicitReturns": true, "importHelpers": true, "lib": ["es6", "dom"], "typeRoots": ["node_modules/@types"], "outDir": "./dist", "rootDir": "./src" }, "include": [ "./src/**/*.ts" ], "exclude": [ "node_modules", "dist", "**/*.test.ts", ] }
|
2.数据类型
1)原始类型
TypeScript的原始类型包括: boolean、number、string、void、undefined、null、symbol、bigint。
注意,开头是小写的,如果你在Typescript文件中写成 Boolean 那代表是 JavaScript 中的布尔对象,这是新手常犯的错误。
void:
表示没有任何类型,当一个函数没有返回值时,你通常会见到其返回值类型是 void:
1 2 3 4 5 6
| function hi(): void { console.log("hello world"); }
const a: void = undefined
|
默认情况下 null 和 undefined 是所有类型的子类型,就是说你可以把 null 和 undefined 赋值给 number 类型的变量。
但是在正式项目中一般都是开启 –strictNullChecks 检测的,即 null 和 undefined 只能赋值给 void 和它们各自。
2)顶级类型
any:
使用any类型来标记那些在编程阶段还不清楚类型的变量,使他们通过编译阶段的检查,比如来自用户输入或第三方代码库等动态内容。
1 2 3
| let b: any = 4; b = "maybe a string instead";
|
unknown
unknown 是 TypeScript 3.0 引入了新类型,是 any 类型对应的安全类型。
unknown 和 any 的主要区别是 unknown 类型会更加严格:在对unknown类型的值执行大多数操作之前,我们必须进行某种形式的检查,而在对 any 类型的值执行操作之前,我们不必进行任何检查。
解释一下,虽然它们都可以是任何类型,但是当 unknown 类型被确定是某个类型之前,它不能被进行任何操作比如实例化、getter、函数执行等等。而 any 是可以的,这也是为什么说 unknown 是更安全的。
如果这么说不够形象,我们看下例子就明白了:
相同点:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| let value1: any;
value1 = true; value1 = 1; value1 = "Hello World"; value1 = Symbol("type"); value1 = {} value1 = []
let value2: unknown;
value2 = true; value2 = 1; value2 = "Hello World"; value2 = Symbol("type"); value2 = {} value2 = []
|
不同点:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| let value1: any;
value1.foo.bar; value1(); new value1(); value1[0][1];
let value2: unknown;
value2.foo.bar; value2(); new value2(); value2[0][1];
|
3)底部类型
never
never 类型表示的是那些永不存在的值的类型,never 类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是 never 的子类型或可以赋值给 never 类型,即使any也不可以赋值给never。(除了never本身之外)。
example:
1 2 3 4 5 6 7
| function error(message: string): never { throw new Error(message); }
const empty: never[] = []
|
4)object
1 2 3 4 5 6 7 8 9 10 11
| enum Color { red = 1 }
let value: object
value = Color value = [1] value = [1, 'hello'] value = {}
|
数组
1 2 3 4 5 6
|
const arr: Array<number> = [1, 2, 3]
const arr: number[] = [1, 2, 3]
|
元组(Tuple)
表示已知元素数量和类型,但各元素的类型不必相同的数组。(可看成严格版的数组)
1 2 3 4 5 6 7
| let tuple: [string, number]; tuple = ['hello', 10];
tuple = ['hello', 10, false] tuple = ['hello'] tuple = [10, 'hello'];
|
枚举类型
1)数字枚举(默认)
当我们声明一个枚举类型是,未赋值时默认是数字类型,而且默认从0开始依次累加。
1 2 3 4 5 6 7 8 9 10 11
| enum Color { Red, Blue, Green, Yellow }
console.log(Color.Red === 0); console.log(Color.Blue === 1); console.log(Color.Green === 2); console.log(Color.Yellow === 3);
|
给第一个值赋值后,之后的值会根据第一个值进行累加。
1 2 3 4 5 6 7 8 9 10 11
| enum Color { Red = 3, Blue, Green, Yellow }
console.log(Color.Red === 3); console.log(Color.Blue === 4); console.log(Color.Green === 5); console.log(Color.Yellow === 6);
|
2)字符串枚举
1 2 3 4 5 6 7 8
| enum Color { Red = 'Red', Blue = 'Blue', Green = 'Green', Yellow = 'Yellow' }
console.log(Color['Red'], Color.Blue);
|
3)异构枚举(数字和字符串混合)
1 2 3 4
| enum Hybrid{ Horse = 0, Donkey = "donkey", }
|
补充:反向映射
JavaScript 对象一般都是正向映射的,即通过key可以取到value,枚举中,不但可以正向映射还可以反向映射。
通过枚举名字获取枚举值,反之,通过枚举值也可以获取到枚举名字
1 2 3 4 5 6 7 8 9
| enum Color { Red = 3, Blue, Green, Yellow }
console.log(Color.Red); console.log(Color.[3]);
|
补充:枚举的本质
为什么能够反向映射呢?看完枚举类型被编译成JavaScript之后我们就知道原因了:
1 2 3 4 5 6 7
| var Color; (function (Color) { Color[Color["Red"] = 3] = "Red"; Color[Color["Blue"] = 4] = "Blue"; Color[Color["Green"] = 5] = "Green"; Color[Color["Yellow"] = 6] = "Yellow"; })(Color || (Color = {}));
|
原因就是枚举类型编译成特殊结构的对象,(如Color[Color[“Red”] = 3] = “Red”;)从而同时拥有了正反映射的特性。