如何定义含必填name键与未知可选键的TypeScript对象类型?
解决TypeScript中通用排序函数的类型兼容问题
你的问题核心是sortByName函数丢失了输入数组的具体类型信息,导致返回值无法匹配UserInfo[]的类型要求。下面是具体的解决方案:
问题根源
你定义的ObjectWithName是一个包含索引签名的宽泛类型,当UserInfo[]传入sortByName后,函数返回的是ObjectWithName[]——这个类型只保证有name属性,但丢失了UserInfo的其他特定属性(比如id、productsIds等),所以TypeScript会报错,不允许将宽泛类型赋值给更具体的UserInfo[]。
解决方案:使用泛型约束
通过泛型让sortByName函数保留输入数组的原始类型,同时确保元素包含name: string属性:
修改后的完整代码
interface UserInfo { id: number, name: string, productsIds: Array<number>, myProducts: number, competitors: number, isFavorite: boolean, }; declare function getUsersInfo(): Array<UserInfo>; function getAndSortUsersInfo(): Array<UserInfo> { const unsortedUserInfo = getUsersInfo(); return sortByName(unsortedUserInfo); } // 泛型函数,T约束为包含name: string的对象 function sortByName<T extends { name: string }>(array: T[]): T[] { return array.sort( ({name: nameA}, {name: nameB}) => spaceship(nameA, nameB), ); } // 优化spaceship的类型,明确接受字符串参数 function spaceship(elementA: string, elementB: string) { if (elementA < elementB) { return -1; } if (elementA > elementB) { return 1; } return 0; }
关键说明
- 泛型
T extends { name: string }:保证传入的数组元素必须包含name属性且类型为字符串,同时让T自动捕获输入数组的具体类型(比如UserInfo)。 - 函数返回
T[]:直接返回和输入同类型的数组,不会丢失原始类型的任何属性,因此sortByName(unsortedUserInfo)的返回类型就是UserInfo[],完全符合getAndSortUsersInfo的返回类型要求。 - 优化
spaceship的参数类型:由于我们明确知道传入的是name字符串,把参数类型从any改为string,提升类型安全性。
内容的提问来源于stack exchange,提问作者dgnin
相关产品推荐
相关产品推荐

