【散记】TS-类型取反(排除),你可以这么做!

1,283 阅读2分钟

专栏介绍

工作或输入时遇到的一些问题散记,内容较杂,不属于纯技术分享。闲时可以阅读就当吃颗糖吧!

本章内容

在ts中,对于对象类型描述时不关心其他属性,只关心希望排除的属性。如果使用到了某些属性,希望在编译时提示抛错

部分场景如:后端有多个接口返回相同的固定属性(继承自某个基类),但是不同场景下会有其他属性(扩展类)。而处于某些原因,后端同学对扩展类再进行扩展后,不想删除第n次扩展的属性

前端诉求:能够复用一个已经定义好的接口,但明确知道有哪些属性是不想要的,希望ts编译时抛出错误

见解:场景比较少见,后端同学一般会按照规范化进行开发。此时前端只需要定义一个基础接口再进行扩展即可

// 1. 定义一个不想要包含的联合类型
type notProperties = "eat" | "dance"; 
interface Normal {
  name: string;
  age: number;
  eat: Function;
  dance: Function;
}
// 2. 定义排除部分类型的属性 的基础类型,Normal必须包含所有属性,需要是一个完整结构,否则无法达到效果
type ExcludesProperties<T extends keyof any> = Omit<Normal, T>;
// 3. 定义排除eat
type ExcludesEat = Omit<Normal, "eat">;
// 4. 定义排除dance
type ExcludesDance = Omit<Normal, "dance">;
// 5. 定义使用ExcludesProperties排除某个类型中包含的属性的别名
type ExcludesModle1 = ExcludesProperties<notProperties>;

const data1 = {
  name: "aaa",
  age: 18,
};
const data2 = {
  name: "bbb",
  age: 19,
};
const data3 = {
  name: "ccc",
  age: 20,
  eat: true,
  dance: true,
};
// 6. 直接给变量使用排除类型后会直接抛错,只有在数组定义中时才不会立即抛错。非数组时可以直接使用
// ExcludesProperties、ExcludesEat、ExcludesDance使用同理
const data4: ExcludesModle1 = {
  name: "ddd",
  age: 21,
  eat: () => {}, // 抛错
  dance: () => {}, // 抛错
};

// 7. 数组中使用时,排除后,数组类型定义时不会标识数组值中的类型错误(如data3,带红波浪线),只有在使用到被排除的属性后才会抛错
// 使用排除基础类型 进行动态排除
// const arr:ExcludesProperties<notProperties>[] = [data1, data2, data3]; 
// 使用排除单个属性的类型 进行指定排除
// const arr:ExcludesEat[] = [data1, data2, data3]; 
// 使用排除单个属性的类型 进行指定排除
// const arr:ExcludesDance[] = [data1, data2, data3]; 
// 使用排除了部分属性后的类型,进行指定部分属性排除
const arr: ExcludesModle1[] = [data1, data2, data3]; 
arr.map((i) => {
  i.eat; // 抛错:数组中只有在读写时才会抛错
  i.dance; // 抛错:数组中只有在读写时才会抛错
  return 1;
});
export {};

最后

我是14,一名5+工作经验、base成都的前端工程狮。期待交流与合作

谢谢你的点赞、收藏、评论