typescript基础(6)(析构/泛型)

2,187 阅读3分钟

析构表达式

也叫解构,类似于python中的解包

unction getStock() {
    return {
        code: "IBM",
        price: 100
    }
}
    
var stock = getStock(); //ES5的写法
var code = stock.code;  //ES5的写法
var price = stock.price;//ES5的写法


// 析构表达式的写法
// 效果跟上面的ES5的写法是一样的
var { code, price } = getStock();

// 也可以起个别名,比如
var { code :aaa, price} = getStock();
console.log(aaa);//这样的话aaa也是可以打印出来的呢

嵌套析构函数

var user = {
    username : "xiaoming",
    book: {title:"析构",price:100}
};
var {username, book:{title,price}} = user;
console.log(username)
console.log(title);
console.log(price);

列表析构

var user_list = ["xiaoming1","xiaohui2","xiaohei3","xiaohong4"];
var [xm1,,xh3] = user_list;
// 得到第一个和第三个,第二个元素通过两个逗号省略
console.log(xm1);
console.log(xh3);

var [xm1,xl2, ...others ] = user_list
//得到第一个和第二个元素,剩余成员被others接收

列表嵌套

var arr_list = [
    ["a","b","c","d"],
    ["e","f","g","h"],
];
var [l1,[l2,l3]]= arr_list;
console.log(l1);
console.log(l2,l3);

泛型

让数据类型参数化,保证使用数据过程中的一致性,让我们编写的代码复用性更强,也更加灵活。

泛型函数

function identity<T>(arg: T): T {
    return arg;
}

function loggingIdentity<T>(arg: Array<T>): Array<T> {
    console.log(arg.length);
    return arg;
}

相当于调用函数时输入的是字符串,返回的也必须是字符串,如果是数字的话那么就会报错。


function func<T>(arg:Array<T>):Array<T> {
    console.log(arg.length);
    // arr[0] = 11 ; 报错
    return arg;
}
var arr = ["xiaoming","xiaohei"];
func(arr);

var arr = [300,"xiaoming"];
func(arr); //这样的话就不会报错了

泛型类型

function identity<T>(arg:T):T{
    console.log(typeof arg);
    return arg;
}
let output1=identity<string>('myString'); //手动限定了必须输入string
let output2=identity(arg:'myString'); //根据参数的类型,系统会自动判断
let output3:number=identity<number>(arg:100);
let output4:number=identity(arg:200);
function func<T>(arg:T) :T{
    return arg;
}
let res: {<T>(args:T):T} = func;// res是一个函数,是func的别名函数,此时可以泛型类型指定函数的输入和输出类型

console.log(res(arg:"100"));

泛型接口

接口必修有泛型函数

nterface GenericIdentityFn {
    <T>(arg: T): T;
}

function identity<T>(arg: T): T {
    return arg;
}

let myIdentity: GenericIdentityFn = identity;

泛型类

class Calc<T> {
    num: T;
    add: (x: T, y: T) => T;
    sub: (x: T, y: T) => T;
}

let calc = new Calc<number>();
calc.num = 100;
calc.add = (x, y)=>{ return x + y; };
calc.sub = (x, y)=>{ return x - y; };

console.log(calc.add(2,3));
console.log(calc.sub(2,3));

泛型约束

interface Arr {
    length: number;
}

function func<T extends Arr>(arg: T): T {
    console.log(arg.length);
    return arg;
}

// func(1000); // 报错,因为数值number没有实现Arr接口类型要求的length属性
// func("abc"); // 正确,因为字符串string虽然没有实现Arr借口类型,但是string拥有length属性,所以因为鸭子类型的原因,所以也算实现了Arr接口类型


class Data implements Arr{
    length: number;
}
var data = new Data();
data.length = 10;
// func(data);


// 数组的类型约束
function func2<K extends keyof T, T> (items: K[], obj: T): T[K][] { // T[K][] 为K类型的数组,且满足K为T的key
    return items.map(item => obj[item]);
}

// console.log( func2([1,2],["xiaoming","xiaohong","xiaohei"] ) );
// 输出结果: ["xiaohong", "xiaohei"]

// console.log( func2([1,2,"A"],["xiaoming","xiaohong","xiaohei"] ) ); // 报错,typescript中的数组根本没有A属性
// console.log( func2([1,2,"length"],["xiaoming","xiaohong","xiaohei"] ) ); // 正确,typescript中的数组有length属性

console.log( func2(["username","age"],{"username":"xiaoming","password":"123456","age":21} ) );
// 输出结果: ["xiaoming", 21]