TypeScript

为什么要设计 typescript

JavaScript 是一门动态弱类型语言,对变量的类型非常宽容,而且不会在这些变量和它们的调用者间建立结构化的契约。如果你长期在没有类型约束的环境下开发,就会造成“类型思维”的缺失,养成不良的编程习惯,这也是做前端开发的短板之一,因此使用 TypeScript 对于前端开发者而言是迫切并且必要的。
使用 TypeScript 还能带来其他好处。比如,Visual Studio Code 具有强大的自动补全、导航和重构功能,这使得接口定义可以直接代替文档,同时也提高了开发效率,降低了维护成本。更重要的是,TypeScript 可以帮助团队重塑“类型思维”,使前端开发者从代码的编写者蜕变为代码的设计者。

初识 TypeScript

1、安装 TypeScript

1
npm i -g typescript

2、编译 ts 文件
先创建一个 test.ts 文件,由于 typescript 需要先编译在运行,我们可以通过以下命令编译。

1
tsc test.ts

编译之后会在目录中生成一个 test.js 文件。

ts 类型

类型概述

ts 有以下类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
let isDone: boolean = false;//boolean
let decLiteral: number = 6;//number
let hexLiteral: number = 0xf00d;
let binaryLiteral: number = 0b1010;
let octalLiteral: number = 0o744;
let name: string = "bob";//string
let list: number[] = [1, 2, 3];//数组
let list: Array<number> = [1, 2, 3];//泛型数组
let x: [string, number];//元组
x = ['hello', 10];
enum Color {Red = 1, Green, Blue};//枚举
let c: Color = Color.Green;
let notSure: any = 4;//任意值,any类型能给任意类型的变量赋值
notSure = "maybe a string instead";
notSure = false;
let unusable: void = undefined;//空值,只能赋予它undefined或null
function warnUser(): void {
alert("This is my warning message");
}
let u: undefined = undefined;//undefined
let n: null = null;//null
function error(message: string): never {//never
throw new Error(message);
}

类型断言

类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。 它没有运行时的影响,只是在编译阶段起作用。
类型断言有两种形式。 其一是“尖括号”语法:

1
2
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;

另一个为 as 语法:

1
2
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;

any 与 unknown

声明为 any 的变量能给任意类型赋值,声明为 unknow 的变量不能给其他类型赋值
工作中不推荐使用 any

1
2
3
4
5
6
7
8
9
10
let a: any;
a = "hello";
a = true;
let s: string;
s = a;
console.log(s);//可以,打印ok
let b: unknown;
b = false;
b = 'world';
s = b;//报错

unknown 类型是类型安全的 any,不能直接给别的变量赋值,如果需要给其他变量赋值应先检测 unknown 变量当前的类型或通过类型断言的方式:

1
2
3
4
5
if (typeof b === "string") {
s=b;
}
s=b as string;
s=<string>b

never

never 一般用在函数上,never 类型表示的是那些永不存在的值的类型。 例如, never 类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; 变量也可能是 never 类型,当它们被永不为真的类型保护所约束时。

1
2
3
function error(message: string): never {//never
throw new Error(message);
}

object

声明一个 object 类型的变量:

1
2
3
let objA :object
objA={};
objA=function(){}

我们可以指定一个对象必须有哪些属性:

1
2
3
4
5
let objB:{name : string ,age? : number};
objB={
name:'张三',
age:18
}

加上问号表示该属性可选,可以理解为 c#的可空类型。
上面的写法有一点缺陷,如果使用上面的写法,我们不能给 objB 添加新的属性,如果想添加新的属性可以使用以下写法:

1
2
3
4
5
6
7
8
let objC :{name:string}
objC={name:'李四',age:18,gender:'男'}//报错,无法添加age和gender属性
//解决方法
let objD :{name:string,[propName:string]:any}
objD={name:'王五',age:18,gender:'男'}//正确
//propName译为属性名,不一定写propName,写成什么都行
//[propName:string]指定属性名为string类型
//[propName:string]:any 指定属性值为any类型

设置函数结构的类型

1
2
3
4
5
let f: Function;//用的少
let fn: (a: number, b: number) => number;
fn = function (val1, val2) {
return val1+val2
}

元组

1
2
3
let yz : [string,number];
yz= ['hello',12];
yz=[12,'hello'];//error

枚举

1
2
3
4
5
6
7
8
9
10
11
enum Color{
Red=1,
Green,
Blue
}
class Computer{
//新语法,可以通过该语法创建对应属性
constructor(public name:string,public size:number,public color:Color){}
}
let c = new Computer('戴尔',14.5,Color.Red);
console.log(c.color)

可空类型

有点类似c#的可空类型写法如下:

1
2
3
4
5
6
7
8
let o:{
name?:string,
age:number
}
o={age:25}
function nullAble(a?:string):void{
console.log(a)
}

类型别名

有点类似C语言的typedef
当我们用一下方式声明多个属性时需要写很多代码,我们可以给string | number |boolean类型起一个别名

1
2
3
let a: string | number |boolean
let b: string | number |boolean
let c: string | number |boolean

type别名:

1
2
3
type myType = string | number |boolean;
let a:myType;
let b:myType

注意:别和C#的type搞混了