泛型
许多时候,标注的具体类型并不能确定,比如一个函数的参数类型
在像C#和Java这样的语言中,可以使用泛型
来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。
1
| function getVal(obj, k) { return obj[k];}
|
上面的函数,我们想实现的是获取一个对象指定的 k 所对应的值
那么实际使用的时候,obj 的类型是 不确定的 自然 k 的取值范围也是不确定的
它需要我们在具体调用的时候才能确定
这个时候这种定义过程不确定类型的需求就可以通过泛型来解决
1
| function getVal<T>(obj: T, k: keyof T) { return obj[k];}
|
所谓的泛型,就是给可变(不定)的类型定义变量(参数), <> 类似 ()
泛型类
在面向对象章节中,我们曾经给大家讲过一个基于泛型使用的例子:模拟组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| abstract class Component<T1, T2> { props: T1; state: T2; constructor(props: T1) { this.props = props; } abstract render(): string; }
interface IMyComponentProps { val: number; }
interface IMyComponentState { x: number; } class MyComponent extends Component<IMyComponentProps, IMyComponentState> { constructor(props: IMyComponentProps) { super(props); this.state = { x: 1 } }
render() { this.props.val; this.state.x; return '<myComponent />'; } } let myComponent = new MyComponent({val: 1}); myComponent.render();
|
泛型接口
我们还可以在接口中使用泛型 后端提供了一些接口 用以返回一些数据
依据返回的数据格式定义如下接口:
1 2 3 4 5
| interface IResponseData { code: number; message?: string; data: any; }
|
根据接口,我们封装对应的一些方法
1 2 3 4 5 6 7
| function getData(url: string) { return fetch(url).then(res => { return res.json(); }).then( (data: IResponseData) => { return data; }); }
|
但是,我们会发现该接口的 data 项的具体格式不确定,不同的接口会返回的数据是不一样的,当我们 想根据具体当前请求的接口返回具体 data 格式的时候,就比较麻烦了,因为 getData 并不清楚你调 用的具体接口是什么,对应的数据又会是什么样的
这个时候我们可以对 IResponseData 使用泛型
1 2 3 4 5
| interface IResponseData<T> { code: number; message?: string; data: T; }
|
1 2 3 4 5 6 7
| function getData<U>(url: string) { return fetch(url).then(res => { return res.json(); }).then( (data: IResponseData<U>) => { return data; }); }
|
定义不同的数据接口
1 2 3 4 5 6 7 8 9 10 11 12
| // 用户接口 interface IResponseUserData { id: number; username: string; email: string; } // 文章接口 interface IResponseArticleData { id: number; title: string; author: IResponseUserData; }
|
调用具体代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ~(async function(){ let user = await getData<IResponseUserData>(''); if (user.code === 1) { console.log(user.message); } else { console.log(user.data.username); } let articles = await getData<IResponseArticleData>(''); if (articles.code === 1) { console.log(articles.message); } else { console.log(articles.data.id); console.log(articles.data.author.username); } });
|