一. 数据类型
变量可以使用数据类型修饰, 限制了变量别随意赋值带来的不可预测性
let age: number = 12;let isDone: boolean = false;let myName: string = 'Tom';let unusable: void = undefined;let u: undefined = undefined;let n: null = null;
有的时候数据类型是不可预测的, 有的场景下, 也是需要可以接受任意类型的变量. 这时候就可以使用任意值
let anyThing: any = 'hello'; anyThing = 3;
类型推断
在声明时,给定了值, 那么变量就会被推断对应的类型.
let myFavoriteNumber = 'seven'; // let myFavoriteNumber: string = 'seven';myFavoriteNumber = 7;
如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any 类型而完全不被类型检查:
let something; // let something: any;something = 'seven'; something = 7; something.setName('Tom');
联合类型
一个类型可以同时指定多个类型
let myFavoriteNumber: string | number; myFavoriteNumber = 'seven'; myFavoriteNumber = 7;
当使用联合类型时, 变量只能使用两个类型中公共的方法和属性.
如果是我们需要在方法中根据类型调用特定的方法时, 就需要使用
断言
语法.断言
只能从联合类型中选取类型
对象类型---接口
程序开发有一个很流行的模式,就是面向接口编程. 接口抽象了结构, 真正的实现就可以提供多种多样的能力.
interface Person { name: string; // name是确定属性, 实现接口的对象,必须失效该属性 age?: number; // age是可选属性, 也就是真正实现时,不需一定实现. readonly id: number; // 只读属性, }let tom: Person = { name: 'Tom', age: 25, id: 100, // 只能在对象赋值时设置值. };
数组的类型
let fibonacci: number[] = [1, 1, 2, 3, 5];// 报错, 数组中只允许单一类型let fibonacci2: number[] = [1, '1', 2, 3, 5];// 泛型数组let fibonacci: Array<number> = [1, 1, 2, 3, 5]; // 接口类型数组interface NumberArray { [index: number]: number; }let fibonacci: NumberArray = [1, 1, 2, 3, 5]; // 要求数组中存放不同类型的值let list: any[] = ['Xcat Liu', 25, { website: 'http://xcatliu.com' }];
函数的类型
注意,输入多余的(或者少于要求的)参数,是不被允许的:
function sum(x: number, y: number): number { return x + y; } sum(1, 2); // 正常sum(1, 2, 3);// 多输入一个参数, 会报错
使用可选参数, 可以省略参数的输入, 可选参数一定要在参数列表的尾部.
function buildName(firstName: string, lastName?: string) { if (lastName) { return firstName + ' ' + lastName; } else { return firstName; } }let tomcat = buildName('Tom', 'Cat');let tom = buildName('Tom');
用接口定义函数的类型
interface SearchFunc { (source: string, subString: string): boolean; }let mySearch: SearchFunc; mySearch = function(source: string, subString: string) { return source.search(subString) !== -1; }
声明文件: declare
我们需要使用 declare
关键字来定义它的类型,帮助 TypeScript 判断我们传入的参数类型对不对:
declare var jQuery: (selector: string) => any; jQuery('#foo');
注意:
通常声明文件放到一个单独的文件中管理. 例如:
jQuery.d.ts
用「三斜线指令」表示引用了声明文件,
/// <reference path="./jQuery.d.ts" />
第三方声明文件,
npm install @types/jquery --save-dev
Node
Node.js 不是内置对象的一部分,如果想用 TypeScript 写 Node.js,则需要引入第三方声明文件:
npm install @types/node --save-dev
二. 进阶用法
关键字: type
类型别名
例如定义一个函数的类型, 参数类型加上返回值类型, 导致类型描述很长, 这时候就可以使用类型别名简化.
type Name = string;type NameResolver = () => string;type NameOrResolver = Name | NameResolver;function getName(n: NameOrResolver): Name { if (typeof n === 'string') { return n; } else { return n(); } }
字符串字面量类型
作为类型时, 参数只能是约定好的内容. 类似于枚举
type EventNames = 'click' | 'scroll' | 'mousemove';function handleEvent(ele: Element, event: EventNames) { // do something} handleEvent(document.getElementById('hello'), 'scroll'); // 没问题handleEvent(document.getElementById('world'), 'dbclick'); // 报错,event 不能为 'dbclick'
元祖
数组: 相同元素集合,
元祖: 不同元素集合
let xcatliu: [string, number]; xcatliu[0] = 'Xcat Liu'; xcatliu[1] = 25; xcatliu[0].slice(1); xcatliu[1].toFixed(2);// 报错, 类型不一致let k: [string, number] = [18,'Tom', 18]
注意:
元素的定义时的位置是固定的.
[18,'Tom', 18]
的类型就是[number, string, number]
对应位置可以使用该位置类型的方法,
如果在元祖中
push
额外元素的类型为元祖中元素的联合类型
number | string
关键字: enum
一般枚举
enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
编译后
var Days; (function (Days) { Days[Days["Sun"] = 0] = "Sun"; Days[Days["Mon"] = 1] = "Mon"; Days[Days["Tue"] = 2] = "Tue"; Days[Days["Wed"] = 3] = "Wed"; Days[Days["Thu"] = 4] = "Thu"; Days[Days["Fri"] = 5] = "Fri"; Days[Days["Sat"] = 6] = "Sat"; })(Days || (Days = {})); ;
它的默认值,如下每个较前一个
+ 1
console.log(Days["Sun"] === 0); // trueconsole.log(Days["Mon"] === 1); // trueconsole.log(Days[2] === "Tue"); // trueconsole.log(Days[6] === "Sat"); // true
手动赋值, 以最后面的数值递增.
enum Days {Sun = 7, Mon = 1, Tue, Wed, Thu, Fri, Sat};console.log(Days["Sun"] === 7); // trueconsole.log(Days["Mon"] === 1); // trueconsole.log(Days["Tue"] === 2); // trueconsole.log(Days["Sat"] === 6); // true
常数枚举
每一项的内容是常数, 不可计算得到.
const enum Directions { Up, Down, Left, Right }let dir: Directions = Directions.Up
编译后
var dir = 0 /* Up */;
外部枚举
// 此处必须使用const, 不然declare 定义的类型只会用于编译时的检查,编译结果中会被删除。declare const enum Directions { Up, Down, Left, Right }let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right];
编译结果:
var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */];
三. 类的使用
访问修饰符
public : 任何地方都可以被访问, 默认的属性和方法都是
publick
private: 只有当前类可以访问.
protected: 和
private
类似, 但可以被子类访问.
抽象类
abstract
用于定义抽象类和其中的抽象方法.
使用关键字 extends
继承抽象类
注意:
抽象类不能被实例化
抽象方法必须被子类实现
接口
接口可以描述一个对象属性, 同时可以对行为
进行抽象
使用关键字
implements
实现接口一个类可以实现多个接口
接口之间可以是继承关系
interface Alarm { alert(); }interface Light { lightOn(); lightOff(); }interface FlyableAlarm extends Alarm{ fly(); }class Door { }class SecurityDoor extends Door implements Alarm { alert() { console.log('SecurityDoor alert'); } }class Car implements Alarm, Light { alert() { console.log('Car alert'); } lightOn() { console.log('Car light on'); } lightOff() { console.log('Car light off'); } }class Plane implements FlyableAlarm{ alert(){ console.log('Plane alert'); } fly(){ console.log('Plane fly'); } }
接口继承类
class Point { x: number; y: number; }interface Point3d extends Point { z: number; }let point3d: Point3d = {x: 1, y: 2, z: 3};
泛型
定义函数,接口或类的时候, 不预先指定具体的类型, 而在使用的时候再指定类型的一种特性
函数使用泛型
function createArray<T,N extends number>(length: N, value: T): Array<T> { let result: T[] = []; for (let i = 0; i < length; i++) { result[i] = value; } return result; } createArray<string>(3, 'x'); // ['x', 'x', 'x']
接口使用泛型
interface CreateArrayFunc { <T>(length: number, value: T): Array<T>; }// 也可以把泛型提升到接口名上//interface CreateArrayFunc<T> {// (length: number, value: T): Array<T>;//}let createArray: CreateArrayFunc; createArray = function<T>(length: number, value: T): Array<T> { let result: T[] = []; for (let i = 0; i < length; i++) { result[i] = value; } return result; } createArray(3, 'x'); // ['x', 'x', 'x']
类使用泛型
class GenericNumber<T> { zeroValue: T; add: (x: T, y: T) => T; }let myGenericNumber = new GenericNumber<number>(); myGenericNumber.zeroValue = 0; myGenericNumber.add = function(x, y) { return x + y; };
指定泛型的默认类型
function createArray<T = string>(length: number, value: T): Array<T> { let result: T[] = []; for (let i = 0; i < length; i++) { result[i] = value; } return result; }
作者:rxdxxxx
链接:https://www.jianshu.com/p/614fd3183908