TypeScript中泛型对象使用keyof T不符合string约束报错是什么原因
问题原因
- 你的
Columns<T>泛型对入参的约束是T extends string,要求传入的类型必须是字符串类型 - TypeScript中
keyof关键字返回的是对象所有键的联合类型,对象键允许是string、number、symbol三种类型。哪怕你给T加了{code: string}的约束,也不限制T可以存在数字或symbol类型的键,所以keyof T的类型是string | number | symbol,不符合Columns要求的入参必须是string的约束,因此抛出类型错误。
解决方案
你可以根据业务场景选择以下任意一种方案修复:
方案1:提取T的字符串类型键
如果你不想修改原有Column/Columns的类型定义,可以用Extract工具类型过滤出keyof T中属于string的部分:
function TableView<T extends { code: string }>() { // 把keyof T替换为Extract<keyof T, string> return forwardRef<HTMLDivElement, { data: T[], columns: Columns<Extract<keyof T, string>> }>( (props, ref) => {
方案2:约束T的所有键都为字符串类型
如果你的业务场景里T的所有键本身就应该是字符串,可以直接给T加上Record<string, any>的约束,这样keyof T就只会返回string类型:
// 给T增加Record<string, any>约束 function TableView<T extends Record<string, any> & { code: string }>() { return forwardRef<HTMLDivElement, { data: T[], columns: Columns<keyof T> }>( (props, ref) => {
方案3:放宽Columns的泛型约束
如果你的业务允许Column的field字段可以是数字或symbol类型,可以直接修改Column/Columns的泛型约束:
// 将泛型约束从string放宽为string | number | symbol export interface Column<T extends string | number | symbol> { field: T; label: string; align?: "left" | "center" | "right" format?: "number" | "integer" | "percent" | "timestamp" | "text" backgroundColor?: (row: any) => string } type Columns<T extends string | number | symbol> = Column<T>[]
内容的提问来源于stack exchange,提问作者edoedoedo
相关产品推荐
相关产品推荐

