安装

1
2
3
4
npm install typescript -g   
npm install tslib -g
npm i @types/node --save-dev (node环境支持的依赖必装)
npm i ts-node --g

运行

第一种:切到代码文件目录想下,在命令行执行:tsc xxx.ts转换成js,然后再通过node运行js文件。

第二种:ts-node xxx.ts

基础类型

1、字符串

1
2
3
4
5
6
// ts声明什么类型就必须是什么类型
// 普通声明
let a: string = "TS";
// 也可使用es6模板语法
let muban: string = `web ${a}`;
console.log(muban);

``是ES6中的模板语法,${a}用来在模板字符串中嵌入表达式。

2、数字类型

支持十六进制、十进制、八进制和二进制。

1
2
3
4
5
6
7
8
9
10
11
// 数字
let notANumber: number = NaN; //Nan
let num: number = 123; //普通数字
let infinity: number = Infinity; //无穷大
let decimal: number = 6; //十进制
let hex: number = 0xf00d; //十六进制
let binary: number = 0b1010; //二进制
let octal: number = 0o744; //八进制

let nums: number = 0;
console.log(nums);

3、布尔类型

1
2
3
4
5
6
// 可以直接使用布尔值
let bool: boolean = true;
// 也可以通过函数返回布尔值
let bool2: boolean = Boolean(1);
console.log(bool);
console.log(bool2);

如下这样会报错:

1
2
3
4
5
let createdBoolean: boolean = new Boolean(1)
// new Boolean() 返回的是一个 Boolean 对象
// 需要改成如下写法 Boolean大写
let createdBoolean: Boolean = new Boolean(1)
// 通过.valueOf()方法可把里面的值读出来

4、空值类型

JavaScript 没有空值(Void)的概念,在 TypeScript 中,可以用 void 表示没有任何返回值的函数。

1
2
3
4
5
6
7
8
9
10
11
// void定义undefined和null类型
let u: void = undefined;
let n: void = null;
console.log(u, n);

// 也可定义空的函数,定义了之后函数就不能又返回值了
// 可直接不写或者返回空
function fnVoid(): void {
return;
}
fnVoid();

如果tsconfig.json开启了严格模式:

1
2
3
4
5
{
"compilerOptions":{
"strict": true
}
}

null不能赋予void类型

5、Null和undefined类型

1
2
3
4
// 定义null和undefined类型
let u: undefined = undefined;
let n: null = null;
console.log(u, n);

void和undefined和null最大的区别是:undefinednull 是所有类型的子类型,也就是说 undefined 类型的变量,可以赋值给 string 类型的变量:

1
2
3
4
5
//这样写会报错 void类型不可以分给其他类型
let test: void = undefined
let num2: string = "1"

num2 = test
1
2
3
4
5
6
7
8
9
10
11
//这样是没问题的
let test: null = null
let num2: string = "1"

num2 = test

//或者这样的
let test: undefined = undefined
let num2: string = "1"

num2 = test

任意类型

Any类型和unknown顶级类型

Any类型没有强制限定哪种类型,随时切换类型都可以,对Any进行的任何操作,不需要检查类型。

1
2
3
4
let anys: any = 123;
anys = "234";
anys = true;
console.log(anys);

声明变量的时候没有指定任意类型默认为any

1
2
3
let anys;
anys = '123'
anys = true

弊端如果使用any 就失去了TS类型检测的作用.

typescript3.0中引入的 unknown 类型也被认为是 top type ,但它更安全。与 any 一样,所有类型都可以分配给unknown

unknow unknow类型比any更加严格当你要使用any 的时候可以尝试使用unknow。

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 value: unknown;
value = true;
value = 42;
value = "hhh";
value = [];
value = {};
value = null;
value = undefined;
value = Symbol("type");

// 这样写会报错unknow类型不能作为子类型只能作为父类型
// any可以作为父类型和子类型
// unknown类型不能赋值给其它类型
let num: unknown = "123";
let nums: string = names;

// 这样写就没问题 any类型是可以的
let num1: any = "123";
let num2: string = num1;

//unknown可赋值对象只有unknown和any
let num3: unknown = "12321";
let num4: any = 321;
num4 = num3;

如果是any类型,在对象没有这个属性的时候,去获取是不会报错的。

1
2
let a: any = {a:111}
a.a

如果是unknow是不能调用属性和方法的

1
2
3
let a:unknown = {b:1,c:():number=>111}
a.b
a.c()

接口与对象类型

对象的类型

在typescript中,我们定义对象的方式需要用到关键字interface(接口), 我的理解是使用interface来定义一种约束,让数据的结构满足约束的格式。定义方式如下:

1
2
3
4
5
6
7
8
9
10
11
// 这样写是会报错的 因为我们在person定义了 a,b但是对象里面缺少b属性
// 使用接口约束不能多也不能少 必须与接口保持一致

interface Person {
a: string;
b: string;
}
const person: Person = {
a: "2131",
};

重名的interface 可以合并:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
interface Person {
a: string;
b: string;
}
interface Person {
age: number;
}
const person: Person = {
a: "2131",
b: "123",
age: 123,
};
console.log(person);


继承:

1
2
3
4
5
6
7
8
9
10
interface A {
name: string;
}
interface B extends A {
age: number;
}
let c: B = {
age: 12,
name: "张三",
};

可选属性 ?操作符

1
2
3
4
5
6
7
8
9
// 可选属性的含义是该属性可以不存在
interface Person {
a: string;
b?: string;
}
const person: Person = {
a: "123",
};
console.log(person);

任意属性[propName: string]

需要注意,一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集

1
2
3
4
5
6
7
8
9
10
11
12
13
// [propName: string]: any;允许添加新的任意属性
interface Person {
a: string;
b?: number;
[propName: string]: any;
}

const person: Person = {
a: "123",
c: "213",
d: 312,
};
console.log(person);

只读属性readonly

readonly 只读属性是不允许被赋值的只能读取

1
2
3
4
5
6
7
8
9
10
11
interface Person {
readonly a: string;
b?: number;
[propName: string]: any;
}
const person: Person = {
a: "123",
c: 123
}
// 这样写会报错, 因为a是只读属性不允许重新赋值
person.a = "312"

添加函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
interface Person {
readonly a: string;
b?: number;
[propName: string]: any;
func(): void;
}

const person: Person = {
a: "123",
c: "123",
func: () => {
console.log(666);
},
};
person.func();
console.log(person);

数组类型

类型[]

1
2
3
4
5
6
7
8
// 类型加中括号
let arr: number[] = [123];
// 定义了数字类型,不允许其它
let arr1: number[] = [1, 2, 3, "1"];
// 操作方法可同类型,不可以添加不同
let arr2: number[] = [1, 2, 3];
arr2.unshift(4);
console.log(arr2);

数组泛型

1
2
3
let arr: Array<number> = [1, 2, 3, 4];
let arr1: Array<string> = ["1", "2"];
console.log(arr, arr1);

用接口表示数组

1
2
3
4
5
6
// 索引的类型是数字,值是字符串
interface NumberArray {
[index: number]: string;
}
let fibona: NumberArray = ["1", "2"];
console.log(fibona);

多维数组

1
2
3
4
5
6
7
8
9
10
11
// 常规的方式
let arr: number[][] = [
[1, 2],
[3, 4],
];
// 泛型
let arr1: Array<Array<number>> = [
[1, 2],
[3, 4],
];
console.log(arr1);

arguments类数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function Arr(...args: any): void {
console.log(arguments);
// 错误的arguments 是类数组不能这样定义
let arr: number[] = arguments;
}
Arr(111, 222);

function Arr(...args: any): void {
console.log(arguments);
//ts内置对象IArguments 定义
let arr: IArguments = arguments;
}
Arr(111, 222);

//其中 IArguments 是 TypeScript 中定义好了的类型,它实际上就是:
interface IArguments {
[index: number]: any;
length: number;
callee: Function;
}

any在数组中的应用

1
let list: any[] = ["test", 1, [], { a: 1 }];

函数扩展

函数的类型

1
2
3
4
5
6
// 参数不能多传,也不能少传 必须按照约定的类型来
const fn = (name: string, age: number): string => {
return name + age;
};
console.log(fn("张三", 18));

函数的可选参数?

1
2
3
4
5
// 通过?表示该参数为可选参数
const fn = (name: string, age?: number): string => {
return name + age;
};
console.log(fn("张三"));

函数参数的默认值

1
2
3
4
const fn = (name: string, age: number = 123): string => {
return name + age;
};
console.log(fn("张三"));

接口定义函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
interface Add {
(num: number, num2: number): number;
}
const fn: Add = (num: number, num2: number): number => {
return num + num2;
};
console.log(fn(1, 3));

interface user {
name: string;
age: number;
}
function getUser(user: user): user {
return user;
}
console.log(getUser({ name: "213", age: 123 }));

定义剩余参数

1
2
3
4
5
6
const fn = (array: number[], ...items: any[]): any[] => {
console.log(array, items);
return items;
};
let a: number[] = [1, 2, 3];
console.log(fn(a, "4", "5"));

函数重载

重载是方法名字相同,而参数不同,返回类型可以相同也可以不同

如果参数类型不同,则参数类型英设置为any

参数数量不同可以将不同参数设置为可选

1
2
3
4
5
6
7
8
9
10
function func(params: number): void;
function func(params: string, params2: number, [propName, string]: any): void;
function func(params: any, params2?: any, d?: string): void {
console.log("params:", params);
console.log("params2:", params2);
console.log(d);
}

func(31);
func("123", 321, 123);