如何解决类型'InputType []'的参数不能分配给类型'GenericType []'的参数
我的目的是编写一个辅助函数,该函数的目的是基于作为第二个参数传递的key
来按字母顺序动态地对对象数组(第一个参数)进行排序。
功能:
interface GenericObject {
[key: string]: string;
}
export const sortAlphabetically = (array: Array<GenericObject>,sortBy: keyof GenericObject) => {
let isKeyValid = false;
// check the key exists in the object before attempting to sort by it
if (array.length > 0) {
isKeyValid = array.every(obj => Object.prototype.hasOwnProperty.call(obj,sortBy) && typeof obj[sortBy] === 'string');
}
if (isKeyValid) {
array.sort((a: GenericObject,b: GenericObject) =>
a[sortBy].toLowerCase() < b[sortBy].toLowerCase()
? -1
: a[sortBy].toLowerCase() > b[sortBy].toLowerCase()
? 1
: 0,);
return array;
} else {
return;
}
};
所以现在,即使在能够测试我的功能之前,如果我尝试这样做:
export interface Person {
name: string;
surname: string;
}
const people: Person[] = [
{name: 'John',surname: 'Smith'},{name: 'Tony',surname: 'Denver'},{name: 'Mary',surname: 'Howard'},]
sortAlphabetically(people,'name');
或者这个:
export interface Car {
model: string;
make: string;
}
const cars: Car[] = [
{model: 'Golf',make: 'Volkswagen'},{model: 'X1',make: 'BMW'},{model: 'Clio',make: 'Renault'},]
sortAlphabetically(cars,'make');
我得到了错误:
TS2345: Argument of type 'Person[]' is not assignable to parameter of type 'GenericObject[]'. Type 'Person' is not assignable to type 'GenericObject'. Index signature is missing in type 'Person'.
Car[]
也会发生同样的情况。
作为辅助函数,关键在于它需要适应any
类型的对象,该对象将在数组内传递,而无需抱怨类型。
因此,我很确定问题出在定义GenericObject
的方式上。
有人可以指出我在这里想念的东西吗?非常感谢。
解决方法
首先,您不应该将Person
投射到GenericObject
,因为Person
在{{1}时拥有number
和string
值}仅允许GenericObject
值。
第二,关于您遇到的错误,还有一个未解决的问题
https://github.com/microsoft/TypeScript/issues/15300
您应将string
替换为interface
type
,
嗯,首先要说一个适当的实现会很麻烦。
您要寻找的东西:
- 传递数组
- 传递属于字符串属性的键
- 按该键对数组进行排序。
对于上述内容,您需要做一些事情:
- 缩小键参数以仅允许使用字符串属性
-
GenericObject
类型不足以单独提供此功能 - 您需要一些仅过滤字符串属性的类型映射器
-
- 由于
GenericObject
和Person
类型之间没有关系,因此您无法进行这种强制转换:array.sort((a: GenericObject,b: GenericObject)
- 如果将数组类型概括为
any
ish类型,则此方法将无效:a[sortBy].toLowerCase()
,因为.toLowerCase()
必须适用于任何类型的对象属性。 因此,您需要一个类型保护将其属性缩小为GenericObject
所以TL; DR
interface GenericObject {
[key: string]: string;
}
type FilterFlags<Base,Condition> = {
[Key in keyof Base]:
Base[Key] extends Condition ? Key : never
};
type AllowedNames<Base,Condition> =
FilterFlags<Base,Condition>[keyof Base];
type SubType<Base,Condition> =
Pick<Base,AllowedNames<Base,Condition>>;
export function sort<T>(array: Array<T>,sortBy: keyof SubType<T,string>) {
let isKeyValid = false;
// check the key exists in the object before attempting to sort by it
if (array.length > 0) {
isKeyValid = array.every(obj => Object.prototype.hasOwnProperty.call(obj,sortBy));
}
if (isKeyValid) {
array.sort((a,b) =>
(isGeneric(a,sortBy) && isGeneric(b,sortBy)) ? // narrow down type to GenericObject so that .toLowerCase becomes valid here
a[sortBy].toLowerCase() < b[sortBy].toLowerCase()
? -1
: a[sortBy].toLowerCase() > b[sortBy].toLowerCase()
? 1
: 0 :
1 // this shouldn't be happening
);
return array;
} else {
return;
}
};
const isGeneric = (a: any,key: keyof typeof a): a is GenericObject =>
typeof a[key] === "string";
export interface Person {
id: number;
name: string;
}
const people: Person[] = [
{ name: 'John',id: 1 },{ name: 'Tony',id: 2 },{ name: 'Mary',id: 3 },]
sort(people,"name"); // this won't allow passing "id" as parameter
SubType
类型的映射器取自here
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。