TypeScript:从字符串索引签名中排除特定字符串
解决TypeScript中排除特定键的索引签名问题
你需要用Exclude<string, ...>来排除特定的字符串字面量,而不是Omit(Omit仅适用于对象类型,不能直接处理string类型)。以下是修正后的实现:
interface Link { href: string; } type MandatoryPaginationLinks = { [key in 'first' | 'last']: Link; }; type OptionalPaginationLinks = { [key in 'prev' | 'next']: Link | null; }; type PaginationLinks = MandatoryPaginationLinks & OptionalPaginationLinks; // 排除四个分页相关键后的字符串类型 type NonPaginationKeys = Exclude<string, 'first' | 'last' | 'prev' | 'next'>; type AdditionalLinks = { [key in NonPaginationKeys]: Link; }; type Links = PaginationLinks & AdditionalLinks; // 测试示例,符合类型要求 const links: Links = { self: { href: 'asdf' }, prev: null, next: { href: '' }, first: { href: 'asdf' }, last: { href: 'asdf' } }; // 错误示例:first不能为null(符合预期) // const invalidLinks: Links = { // self: { href: 'asdf' }, // prev: null, // first: null, // 类型错误:不能将null分配给类型Link // last: { href: 'asdf' } // };
为什么之前的写法无效?
Omit<string, 'first' | ...>是错误用法:Omit的作用是从对象类型中移除指定属性,而string是基础类型,不是对象类型,所以这个写法不会生效。而Exclude<string, T>可以从字符串字面量的联合中排除指定的字面量(TypeScript将string视为所有可能字符串字面量的联合),从而得到排除特定键后的合法索引类型。
这样定义后:
first、last会强制要求是Link类型(必填)prev、next允许是Link或null- 其他任意字符串键必须是Link类型,且不能覆盖前四个键的类型规则
内容的提问来源于stack exchange,提问作者PeterFox
相关产品推荐
相关产品推荐

