前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TypeScript系列教程九《类型转换》-- 映射类型

TypeScript系列教程九《类型转换》-- 映射类型

作者头像
星宇大前端
发布2021-08-20 16:11:37
1.3K0
发布2021-08-20 16:11:37
举报
文章被收录于专栏:大宇笔记

类型转换是TS最好玩也是语言的灵魂,想玩好需要熟练各种手段和工具,下面一一介绍类型转换的一些常用手段。

Mapped Types


有时候对象属性类型重复或者一个类型基于另一个了类型的时候

映射类型基于索引签名的语法构建,用于声明尚未提前声明的属性类型:

代码语言:javascript
复制
type OnlyBoolsAndHorses = {
  [key: string]: boolean | Horse;
};

const conforms: OnlyBoolsAndHorses = {
  del: true,
  rodney: false,
};

泛型映射类型使用keyof 得到联合类型,通过key 迭代创建新类型

代码语言:javascript
复制
type OptionsFlags<Type> = {
  [Property in keyof Type]: boolean;
};

在这个例子里,OptionsFlags将会把Type所有的属性当做key,所有的值类型变成boolean

代码语言:javascript
复制
type FeatureFlags = {
  darkMode: () => void;
  newUserProfile: () => void;
};
 
type FeatureOptions = OptionsFlags<FeatureFlags>;
           
//type FeatureOptions = {
    //darkMode: boolean;
   // newUserProfile: boolean;
//}

映射修饰

有两个附加的修饰符可以在映射期间应用:readonly和?分别影响可变性和可选性。

可以通过在前面加上-或+,删除或添加这些修饰符。如果不添加前缀,则假定为+。

代码语言:javascript
复制
// Removes 'readonly' attributes from a type's properties
type CreateMutable<Type> = {
  -readonly [Property in keyof Type]: Type[Property];
};
 
type LockedAccount = {
  readonly id: string;
  readonly name: string;
};
 
type UnlockedAccount = CreateMutable<LockedAccount>;
           
//type UnlockedAccount = {
    //id: string;
    //name: string;
//}
代码语言:javascript
复制
// Removes 'optional' attributes from a type's properties
type Concrete<Type> = {
  [Property in keyof Type]-?: Type[Property];
};
 
type MaybeUser = {
  id: string;
  name?: string;
  age?: number;
};
 
type User = Concrete<MaybeUser>;
      
//type User = {
    //id: string;
    //name: string;
    //age: number;
//}

key 通过as 重新映射

在TypeScript 4.1及更高版本中,您可以使用映射类型中的as子句重新映射映射映射类型中的键:

代码语言:javascript
复制
type MappedTypeWithNewProperties<Type> = {
    [Properties in keyof Type as NewKeyType]: Type[Properties]
}

您可以利用模板文字类型等功能从以前的属性名称创建新的属性名称:

代码语言:javascript
复制
type Getters<Type> = {
    [Property in keyof Type as `get${Capitalize<string & Property>}`]: () => Type[Property]
};
 
interface Person {
    name: string;
    age: number;
    location: string;
}
 
type LazyPerson = Getters<Person>;
         
//type LazyPerson = {
    //getName: () => string;
    //getAge: () => number;
    //getLocation: () => string;
//}

您可以通过条件类型生成never来筛选出键:

代码语言:javascript
复制
// Remove the 'kind' property
type RemoveKindField<Type> = {
    [Property in keyof Type as Exclude<Property, "kind">]: Type[Property]
};
 
interface Circle {
    kind: "circle";
    radius: number;
}
 
type KindlessCircle = RemoveKindField<Circle>;
           
//type KindlessCircle = {
    //radius: number;
//}

进一步探索

映射类型与此类型操作部分中的其他功能配合得很好,例如,这里有一个使用条件类型的映射类型,该类型根据对象的属性pii是否设置为文本true返回true或false:

代码语言:javascript
复制
type ExtractPII<Type> = {
  [Property in keyof Type]: Type[Property] extends { pii: true } ? true : false;
};
 
type DBFields = {
  id: { format: "incrementing" };
  name: { type: string; pii: true };
};
 
type ObjectsNeedingGDPRDeletion = ExtractPII<DBFields>;
                 
//type ObjectsNeedingGDPRDeletion = {
    //id: false;
    //name: true;
//}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/08/17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Mapped Types
    • 映射修饰
      • key 通过as 重新映射
        • 进一步探索
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档