登录
登录 注册新账号
注册
已有账号登录
晋级TypeScript高手,成为抢手的前端开发人才【完整】分享
原动力 阅读 517 次
1月3日发布

Download: 晋级TypeScript高手,成为抢手的前端开发人才

晋级TypeScript高手,成为抢手的前端开发人才 - TS函数重载丶类方法重载丶类构造器重载

函数重载: 为同一个函数提供多个函数类型定义来进行函数重载。

函数重载其实就是: 多个函数函数名相同,函数的参数类型,顺序,个数不同。注意函数重载与返回值类型无关。ts的函数重载比较鸡肋,最终函数逻辑的实现还是在一个函数体内去判断它的参数类型,然后做相应的操作。ts重载的作用,感觉只是多了一个参数校验的功能。也就是说在进行函数调用的时候,会对参数进行检查,只有传入的参数类型,顺序,个数与定义的重载函数的参数相同,才能调用成功,否则报错。返回值类型不会进行校验(函数重载与返回值类型无关)。

let suits = ["hearts", "spades", "clubs", "diamonds"];
function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any {
// Check to see if we're working with an object/array
// if so, they gave us the deck and we'll pick the card
if (typeof x == "object") {
let pickedCard = Math.floor(Math.random() * x.length);
// return pickedCard;
return 'pickedCard'; // 并不会报错,编译是通过的
}
// Otherwise just let them pick the card
else if (typeof x == "number") {
let pickedSuit = Math.floor(x / 13);
return { suit: suits[pickedSuit], card: x % 13 };
}
}

let myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4 }];
let pickedCard1 = myDeck[pickCard(myDeck)];
alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);

let pickedCard2 = pickCard(15);
alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);
晋级TypeScript高手,成为抢手的前端开发人才 - 泛型
一、泛型类
泛型可以用于类和构造器,例如:

class Person<T>{
private _value: T;
constructor(val: T) {
this._value = val;
}
}
let p = new Person<number>(12)
如上,<T>表示传递一个T类型,在new的时候才把具体类型传入。其中T是变量可改,但通常比较常见就是写T
之前说TypeScript类型的时有说到数组,其实数组本质就是一个泛型类

let a = new Array<number>();
二、泛型函数
泛型可以用于普通函数,例如:

function fn<T>(arg: T): T {
return arg;
}
fn<number>(12);
其实不管是用于类还是用于函数,核心思想都是:把类型当一种特殊的参数传入进去

需要注意的是泛型也可以“继承”,但表示的是限制范围
例如

class Person<T extends Date>{
private _value: T;
constructor(val: T) {
this._value = val;
}
}
let p1 = new Person(new Date())

class MyDate extends Date{}
let p2 = new Person(new MyDate())
以上是泛型的基本使用!

晋级TypeScript高手,成为抢手的前端开发人才 - 高级类型的十八般武艺

交叉类型
交叉类型是将多个类型合并为一个类型,使得这个类型包含了所有类型的特性。
大多数是在混入mixins或者其他不适合典型面向对象模型的地方看到交叉类型的使用。

function extend<T,U>(first: T,second: U):T & U{
let result = <T & U>{};
for (let id in first)
(<any>result)[id] = (<any>first)[id];
for (let id in second)
if(!result.hasOwnProperty(id))
(<any>result)[id] = (<any>second)[id];
}
class Person {
constructor(public name : string){}
}
interface Loggable {
log() : void;
}
class Logger implements Loggable{
log() {
// aaaaaaaaa
}
}

let mix = extend(new Person("yivi"),new Logger());
console.log(mix.name);
mix.log();

联合类型
联合类型作用类似于逻辑操作符——“或”,同样用“|”来分割每个类型。
如果一个值为联合类型,我们只能访问该联合类型的所有类型的公有成员。

interface Bird {
fly();
layEggs();
}
interface Fish {
swim();
layEggs();
}

function getAnimal() : Fish | Bird{
// do something
}
let pet = getAnimal();
pet.layEggs(); // ok
pet.swim(); //error
自定义类型保护
所谓类型保护,就是一些表达式,他们会在运行时检查以确保在某个作用域的类型。

定义一个类型保护,我们只要简单地定义一个函数,返回值类型是一个类型谓词。

谓词为 parameterName is Type这种形式,parameterName必须是来自于当前函数签名里的一个参数名。