Typescript utilitytypes的使用,part 1
2021年1月3日 • ... • ☕️ 2 min read
在日常工作时,处理业务上的数据,很多时候接口返回数据,在用TS定义时,都有繁琐且重复的问题。这些数据结构通常都很简单:用字符串作为key,然后字符串作为value,以此为基础对象,扩展成数组或复杂对象。
Record就可以专门用来检查这种结构的对象。
比如:
result = {
status: 'success',
data: {
id: '1313243',
title: 'Some title',
createTime: '2021-01-03 13:30:00'
},
message: 'OK'
};
为了适配这种格式,我们有必要写个type或者interface,来在其他地方做类型限定。status和message都好说,但是到data的时候,嗯……直接用any吗?
interface IResult {
status: string;
message: string;
data: any;
}
然后除去老师傅告诉你的any弊端,最棘手的是,IDE报警告(错误)了。
我之前一般老老实实写一堆data的数据来匹配结果,或者掩耳盗铃,ignore next line…但是有没有其他办法呢?
直到我最近看文档发现辅助类型这一章,恍然大悟。
interface IResult {
status: string;
message: string;
data: Record<string, string>;
}
这样,即可保证data里的数据是个对象,且key和value均为string。
进一步的操作,可以限定为具体某个对象的key。例如:
type PostType = {
id: string;
title: string;
createTime: string;
}
interface IResult {
status: string;
message: string;
data: Record<keyof PostType, string>;
}
// 定义
const res: IResult = {
status: 'success',
data: {
id: '1313243',
title: 'Some title',
createTime: '2021-01-03 13:30:00'
},
message: 'OK'
};
2、key不固定的对象类型
比如接口返回了以随机ID为key的对象
{
'0ea32fdh': {title: 'some title 1', comments: 12},
'0ea33fdh': {title: 'some title 2', comments: 24},
'0ea34fdh': {title: 'some title 3', comments: 36},
}
如何定义呢?
type PostType = {
title: string;
comment: number;
}
interface IResult {
[k: string]: PostType;
}
或者用Record
type PostContentType = {
title: string;
comments: number;
}
type IPostType = Record<string, PostContentType>;
const post: IPostType = {
'0ea32fdh': {title: 'some title 1', comments: 12},
'0ea33fdh': {title: 'some title 2', comments: 24},
'0ea34fdh': {title: 'some title 3', comments: 36},
}
相对于前一种,使用Record没有使用强制转换,本身看起来也更易读。