1.原始类型
let num: number;let str: string;let bool: boolean;
2.数组
let boolArray: boolean[];let fibonacci: Array<number> = [1, 1, 2, 3, 5]; //数组泛型
3.接口
interface Name {first: string;second: string;third?: boolean //?:表示可选属性//任意属性,一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集:[propName:string]:string|number|booleanreadonly id:number //只读属性,不可被修改}//接口和变量的形状、类型必须保持一致let name: Name;name = {first: 'John',second: 'Doe'};name = {// Error: 'Second is missing'first: 'John'};name = {// Error: 'Second is the wrong type'first: 'John',second: 1337};
4.内联注解
内联类型能为你快速的提供一个类型注解。它可以帮助你省去为类型起名的麻烦(你可能会使用一个很糟糕的名称)。然而,如果你发现需要多次使用相同的内联注解时,考虑把它重构为一个接口(或者是 type alias,)是一个不错的主意。
let name: {first: string;second: string;};
5.特殊类型
1.any 任意类型
2.null 和 undefined
在类型系统中,JavaScript 中的 null 和 undefined 字面量和其他被标注了 any 类型的变量一样,都能被赋值给任意类型的变量,如下例子所示:
let num: number;let str: string;// 这些类型能被赋予num = null;str = undefined;
3.void 函数无返回值
function log(message: string): void {console.log(message);}
6.泛型
//函数 reverse 的返回值类型与它接受的参数的类型一样。当你传入 var sample = [1, 2, 3] 时,1.下面的reverse函数接受类型为T的一个数组T[],返回值也为T[]//TypeScript 能推断出 reverse 为 number[] 类型,从而能给你类型安全。function reverse<T>(items: T[]): T[] {const toreturn = [];for (let i = items.length - 1; i >= 0; i--) {toreturn.push(items[i]);}return toreturn;}const sample = [1, 2, 3];let reversed = reverse(sample);console.log(reversed); // 3, 2, 1// Safetyreversed[0] = '1'; // Errorreversed = ['1', '2']; // Errorreversed[0] = 1; // okreversed = [1, 2]; // ok
7.联合类型 |
当希望使用多个类型之一时,可以采用联合类型。
function formatCommandline(command: string[] | string) {let line = '';if (typeof command === 'string') {line = command.trim();} else {line = command.join(' ').trim();}// Do stuff with line: string}
联合类型的特点:
- 当 TypeScript 不确定一个联合类型的变量到底是哪个类型的时候,我们只能访问此联合类型的所有类型里共有的属性或方法:
- 联合类型的变量在被赋值的时候,会根据类型推论的规则推断出一个类型:
8.交叉类型
//todo9.元组类型
let nameNumber: [string, number];// OknameNumber = ['Jenny', 221345];// ErrornameNumber = ['Jenny', '221345'];
10.函数类型
1.函数声明function sum(x: number, y: number,z?:string): number {return x + y;}2.函数表达式let mySum = function (x: number, y: number): number {return x + y;};3.在 ES6 中,我们允许给函数的参数添加默认值,TypeScript 会将添加了默认值的参数识别为可选参数:function buildName(firstName: string, lastName: string = 'Cat') {return firstName + ' ' + lastName;}4.剩余参数function push(array: any[], ...items: string[]) {items.forEach(function(item) {array.push(item);});}
11.类型推论
如果没有明确的指定类型,那么 TypeScript 会依照类型推论(Type Inference)的规则推断出一个类型。
let myFavoriteNumber = 'seven';//等价于let myFavoriteNumber: string = 'seven';
如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any 类型而完全不被类型检查
12.类型断言
1. <类型>值2. 值 as 类型//egfunction getLength(something: string | number): number {if ((<string>something).length) { //断言为stringreturn (<string>something).length;} else {return something.toString().length;}}在 tsx 语法(React 的 jsx 语法的 ts 版)中必须用后一种。类型断言不是类型转换,断言成一个联合类型中不存在的类型是不允许的:
13.接口和类型别名的区别
- 如果你需要使用类型注解的层次结构,请使用接口。它能使用
implements和extends - 为一个简单的对象类型请使用类型别名
type,只需要给它一个语义化的名字即可。另外,当你想给联合类型和交叉类型提供一个语义化的名称时,一个类型别名将会是一个好的选择。 - 接口可以较容易的拓展。 ```javascript // Lib a.d.ts interface Point { x: number, y: number } declare const myPoint: Point
// Lib b.d.ts interface Point { z: number }
// Your code let myPoint.z // Allowed! ```
