ts中Omit损失类型问题

当Omit剔除的ts本身包含任意键即[key: string],则Omit的类型会丢失其余属性的类型

示例如下:

interface Base {
    data: string[]
    date: [string, string]
    [key: string]: unknown
}
type a = Omit<Base, 'data'> 
type b = a["date"]

此时剔除属性data,预期应当获得类型date与任意键值类型接收,即date可以获得[string, string]的类型提示,但实际a的类型为

// 我们预期的类型
type a = {
    date: [string, string]
    [key: string]: unknown
}

// 实际上获得的类型
type a = {
    [x: string]: unknown;
    [x: number]: unknown;
}

但此时我们去掉 [key: string]类型,结果就符合预期了

interface Base {
    data: string[]
    date: [string, string]
}
type a = Omit<Base, 'data'> 

// 	此时a的符合预期,为剔除属性后的结果
type a = {
    date: [string, string];
}

实际上的原代码大致如下,因为CommonComponents当中的[key: string]: any导致ChartProps无法获得正确类型

解决方案:去掉CommonComponents当中的[key: string]: any

问题原因:问题出在使用 Omit 类型操作符时对带有索引签名(如 [key: string]: unknown)的接口进行操作。TypeScript 在处理带有索引签名的接口时,会将索引签名视为一种更加通用的类型。因此,当你尝试从该接口中剔除某个属性时,TypeScript 会为了保持一致性而将其他属性的类型也更改为索引签名指定的类型。

在你的示例中,Base 接口包含一个索引签名 [key: string]: unknown,这意味着它可以接收任意类型的键值对。当你使用 Omit<Base, 'data'> 时,TypeScript 会将 date 属性的类型也更改为 unknown,以保持一致性。因此,获得的类型与预期不符。

结论:被继承的基础接口类型应当避免使用[key: string]: any,以避免产生后续类型提示上的问题

export interface CommonComponents {

    key: string

    label?: string

    // [key: string]: any
}


export interface CardComponents extends CommonComponents {
    // 省略
}


export interface CardProps extends CardComponents {
    // 省略
}


export type ChartProps = Omit<CardProps, 'data'> & {
    data?: string[][]
}

另一种解决方案:

type OmitIndex<T, K extends keyof T> = {
  [P in keyof T as Exclude<P, K>]: T[P];
};

interface Base {
  data: string[];
  date: [string, string];
  [key: string]: unknown;
}

type a = OmitIndex<Base, 'data'>;
type b = a['date'];
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值