gpt4 book ai didi

typescript - 'InputType[]' 类型的参数不能分配给 'GenericType[]' 类型的参数

转载 作者:行者123 更新时间:2023-12-04 08:57:25 26 4
gpt4 key购买 nike

我的目的是编写一个辅助函数,其目的是根据 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 的方式上。 .
有人可以指出我在这里缺少什么吗?非常感谢。

最佳答案

好吧,首先要说正确的实现会很麻烦。
你寻求什么:

  • 传递一个数组
  • 传递属于字符串属性的键
  • 按该键对数组进行排序。

  • 对于上面的人,你需要做一些事情:
  • 缩小关键参数以仅允许字符串属性
  • 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
    Playground Link SubType类型映射器取自 here

    关于typescript - 'InputType[]' 类型的参数不能分配给 'GenericType[]' 类型的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63738033/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com