当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,以避免产生后续类型提示上的问题文章来源:https://www.toymoban.com/news/detail-516351.html
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[][]
}
另一种解决方案:文章来源地址https://www.toymoban.com/news/detail-516351.html
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'];
到了这里,关于ts中Omit损失类型问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!