参考链接:
一、TypeScript安装
使用TypeScript前需要在系统中全局安装TypeScript,使用npm或yarn进行全局安装
npm install typescript -g
yarn global add typescript
由于Node环境不能直接运行.ts文件,需要用tsc xxx.ts将.ts文件转换为Node可运行的.ts文件,操作的效率比较低,所以这里还需安装ts-node插件,使用ts-node就可以直接看到编写结果,使用npm全局安装
npm install -g ts-node
安装完成后,就可以在命令中直接输入如下命令,来查看编译结果了。
ts-node xxx.ts
二、静态类型/基础数据类型
2.1 静态类型
TypeScript 中,使用 : 指定变量的类型,例如,用 : 指定 person、count类型为 string、number
function hello(person: string){
return 'hello,' + person ;
}
let user = 'lizhien';
console.log(hello(user)); // hello, lizhien
const count: number = 1;
这里就定义了hello函数和count常量的类型为string和number,使用对应类型上所有的属性和方法。
2.2 自定义静态类型
使用了静态类型,不仅意味着变量的类型不可以改变,还意味着类型的属性和方法也跟着确定了
name: string,
age: number
}
const wen: UserName = { name: 'wenshuaige', age: 18 }
console.log(wen) // { name: 'wenminghao', age: 18 }
2.3 基础数据类型
原始数据类型在 TypeScript 中的应用:
-
布尔值:
let isDone: boolean = false;
注意,使用构造函数 Boolean 创造的对象不是布尔值,
let createdByNewBoolean: Boolean = new Boolean(1);
在 TypeScript 中,boolean 是 JavaScript 中的基本类型,而 Boolean 是 JavaScript 中的构造函数。
-
数值:
let count1: number = 6; let count2: number = 0xf11d;// ES6 中的二进制表示法 let binary: number = 0b1010; // ES6 中的八进制表示法 let octalLiteral: number = 0o744; let notANumber: number = NaN; let infinityNumber: number = Infinity;
-
字符串:
let myName: string = 'wmh'; let myAge: number = 18; // 模板字符串语法 let userInfo =
my name is ${myName},i am ${myAge} years old; -
空值:
function alertName(): void { alert('My name is Tom'); } let unusable: void = undefined;
JavaScript 没有空值(Void)的概念,在 TypeScript 中,可以用 void 表示没有任何返回值的函数,声明一个 void 类型的变量,赋值为undefined 和 null
- Null和undefined
在 TypeScript 中,可以使用 null 和 undefined 来定义这两个原始数据类型:
// 这样不会报错
let count: number = undefined;
let m: undefined;
let newM: number = m;
而 void 类型的变量不能赋值给 number 类型的变量:
let count: void;
let newM: number = count;
// Type 'void' is not assignable to type 'number'.
2.4 对象类型
-
对象类型
const myInfo: { name: string, age: number, } = { name: "wen帅哥", age: 18, }; console.log(myInfo.name); // wen帅哥
-
数组类型
const arrayInfo: String[] = ["wen", "shuai", "哥"];
-
类类型
class Person {} const wen: Person = new Person();
-
函数类型
const userName: () => string = () => { return "wenshuai哥"; };
2.5 任意值类型
任意值(Any)用来表示允许赋值为任意类型,
// 任意值赋值允许更改
let anyNumber: any = 'seven';
anyNumber = 7; √
// 普通类型不允许被更改
let myFavoriteNumber: string = 'seven';
myFavoriteNumber = 7; X
在任意值上访问任何属性都是允许的,也允许调用任何方法:
let anyUser: any = 'wmh';
console.log(anyUser.myName);
anyUser.setName('Tom');
变量如果在声明的时候,未指定其类型,那么它会被识别为任意值类型:
let something;
something = 'wmh';
something = 18;
something.setName('Tom');
2.6 类型推论
如果没有明确的指定类型,那么 TypeScript 会依照类型推论(Type Inference)的规则推断出一个类型。
let count = 110;
count = '110';
// hello.ts:42:1 - error TS2322: Type 'string' is not assignable to type 'number'.
2.7 联合类型
表示取值可以为多种类型中的一种,联合类型使用 | 分隔每个类型
let myFavoriteMovie: string | number;
myFavoriteMovie= 'xijuzhiwang';
myFavoriteMovie= 007;
当 TypeScript 不确定一个联合类型的变量到底是哪个类型的时候,我们只能访问此联合类型的所有类型里共有的属性或方法:
function getLength(something: string | number): number {
return something.length;
}
// hello.ts:45:22 - error TS2339: Property 'length' does not exist on type 'string | number'.
Property 'length' does not exist on type 'number'.
// 此时访问不到length属性
function getString(something: string | number): string {
return something.toString();
}
// string和number共有toString()方法可以获取到
联合类型的变量在被赋值的时候,会根据类型推论的规则推断出一个类型:
let myName: string | number;
myName= 'wmh';
console.log(myName.length); // 3myName= 7;
console.log(myName.length); // 编译时报错
// hello.ts:51:20 - error TS2339: Property 'length' does not exist on type 'number'.
三、对象/数组/函数类型
-
对象的类型——Interfaces
interface userInfo{ name: string; age: number; }
let user: userInfo = { name: 'wen', age: 18 };
定义的变量比接口少了一些属性,多一些属性都是不允许的。
有时我们希望定义的变量和接不要完全匹配,那么可以用可选属性:
interface userInfo{ name: string;
age?: number;
}
let user: Person = {
name: 'wen'
};
有时候我们希望一个接口允许有任意的属性,可以使用如下方式:
interface userInfo{ name: string;
age?: number;
[propName: string]: any;
}
let user: userInfo= { name: 'wen',
gender: 'male'
};
需要注意的是,一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集:
interface userInfo{ name: string;
age?: number;
[propName: string]: string;
}
let tom: userInfo= { name: 'wen',
age: 18,
gender: 'male'
};
任意属性的值允许是 string,但是可选属性 age 的值却是 number,number 不是 string 的子属性,所以报错了。
一个接口中只能定义一个任意属性。如果接口中有多个类型的属性,则可以在任意属性中使用联合类型:
interface UserInfo{ name: string;
age?: number;
[propName: string]: string | number;
}
let user: UserInfo= { name: 'wen',
age: 18,
gender: 'male'
};
有时候我们希望对象中的一些字段只能在创建的时候被赋值,那么可以用 readonly 定义只读属性:
interface UserInfo{
readonly id: number;
name: string;
age?: number;
[propName: string]: any;
}
let user: UserInfo= { id: 110,
name: 'wen',
gender: 'male'
};
tom.id = 120;
// hello.ts:65:7 - error TS2540: Cannot assign to 'id' because it is a read-only property.
- 数组的类型
-
最简单的方法是使用「类型 + 方括号」来表示数组:
const numberArr: number[] = [1, 2, 3]; const stringArr: string[] = ["a", "b", "c"]; const undefinedArr: undefined[] = [undefined, undefined];
// 如果数组中有多种类型,比如既有数字类型,又有字符串的时候,采用联合类型的声明方式 const arr: (number | string)[] = [1, "string", 2];
2.接口也可以用来描述数组:
interface NumberArray {
[index: number]: number;
}
let fibonacci: NumberArray = [1, 1, 2, 3, 5];
3.数组中对象类型的定义
const userInfoList: { name: string, age: Number }[] = [
{ name: "wen", age: 18 },
{ name: "pengyuyan", age: 28 },
];
// TypeScript 为我们准备了一个概念,叫做类型别名
type ShuaiGe = { name: string, age: Number };
const userInfoList: ShuaiGe[] = [ { name: "wen", age: 18 },
{ name: "pengyuyan", age: 28 },
];
- 函数的类型
一个函数有输入和输出,要在 TypeScript 中对其进行约束,需要把输入和输出都考虑到:
function total(x: number, y: number): number {
return x + y;
}
// 输入的参数不能多也不能少
total(1)
total(1,2,3)
在 TypeScript 的类型定义中,=> 用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型。
let total: (x: number, y: number) => number = function (x: number, y: number): number {
return x + y;
};
我们也可以使用接口的方式来定义一个函数需要符合的形状:
interface isDone{
(name: string, title: string): boolean;
}
let mySubject: isDone;mySubject= function(name: string, title: string) {
return name.search(title) !== -1;
}
我们用 ? 表示可选的参数:
function myName(xing: string, ming?: string) {
if (ming) {
return xing+ ' ' + ming;
} else {
return xing;
}
}
let wenMing = buildName('wen', 'Ming');
let wen = buildName('wen');
注:可选参数后面不允许再出现必需参数了。
在 ES6 中,我们允许给函数的参数添加默认值,TypeScript 会将添加了默认值的参数识别为可选参数:
function myName(xing: string, ming: string='ming') {
if (ming) {
return xing+ ' ' + ming;
} else {
return xing;
}
}
let wenMing = buildName('wen', 'Ming');
let wen = buildName('wen');