TypeScript如何定义至少包含指定属性的对象参数类型?
你可以通过TypeScript的结构类型兼容特性实现,不需要加[x:string]: any索引签名,有两种常用写法:
写法1:泛型约束(推荐,保留完整类型信息)
如果你需要函数返回值保留传入对象的所有额外属性的类型,用泛型约束即可:
// 泛型T约束为至少包含 {name: {value: string}} 结构 const sortNameV2 = <T extends { name: { value: string } }>( array: T[], sortOrder: 'ASC' | 'DESC' ) => { return [...array].sort((a, b) => { const compareRes = a.name.value.localeCompare(b.name.value) return sortOrder === 'ASC' ? compareRes : -compareRes }) } // 调用正常,返回值类型会自动推导为 Array<{ name: { value: string }, id: number }> const result = sortNameV2([{ name: { value: 'titi'}, id: 1 }], 'ASC')
写法2:直接声明最低结构要求
如果你不需要保留额外属性的类型,直接把数组元素声明为要求的最低结构即可,TypeScript会自动兼容包含更多属性的传入对象:
const sortNameV2 = ( array: Array<{ name: { value: string } }>, sortOrder: 'ASC' | 'DESC' ) => { return [...array].sort((a, b) => { const compareRes = a.name.value.localeCompare(b.name.value) return sortOrder === 'ASC' ? compareRes : -compareRes }) } // 调用完全正常,不会报错 sortNameV2([{ name: { value: 'titi'}, id: 1 }], 'ASC')
原理解释
TypeScript默认采用结构类型判定兼容规则,只要传入的对象包含目标类型声明的所有必填属性,就会被判定为类型兼容,不需要额外声明索引签名。你之前加的[x:string]: any只有在需要动态通过字符串键访问对象未知属性的时候才需要使用,这里你只访问固定的name.value属性,完全不需要加这个声明。
内容的提问来源于stack exchange,提问作者Nicolas Menettrier
相关产品推荐
相关产品推荐

