首页 > 解决方案 > 以任何对象的数组为参数的通用函数

问题描述

我创建了 2 个通用函数,它们将采用任何对象的数组。第一个函数将属性作为字符串和要与给定对象匹配的字符串值。第二个函数将返回id给定对象的最后一个。

// First data
const data = [
    {
        id: 1,
        name: 'John',
    },
    {
        id: 2,
        name: 'Doe',
    },
    {
        id: 3,
        name: 'Tim',
    },
];
// Second data
const data2 = [
    {
        id: 1,
        title: 'John',
    },
    {
        id: 2,
        title: 'Doe',
    },
    {
        id: 3,
        title: 'Tim',
    },
];


export const matchStr = <T>(key: string, val: string, data: Array<T>): string => {

    if (Array.isArray(data) && data.length > 0) {
        const result = data.find((obj) => {
            return obj[key] === val;
        });
        // If not undefined
        if (result) {
            return `${key} value is matched.`;
        } else {
            // Return value
            return val;
        }
    }
    return val;
};


export const getLastId = <T>(data: Array<T>): number => {
    if (Array.isArray(data) && data.length > 0) {
        // Create an array of Id's of all items
        const idsArray: number[] = [];
        data.forEach((obj) => {
            idsArray.push(obj.id);
        });
        // Return last element id
        return idsArray[data.length - 1];
    } else {
        return 1;
    }
};


const resultSet1 = matchStr('name', 'John', data);
const resultSet2 = matchStr('name', 'George', data2);

console.log(resultSet1);
console.log(resultSet2);

const resultId = getLastId(data);

console.log(resultId);

但是以下几行给了我一个错误:

在第一个功能上:

obj[key] === val

TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'unknown'. No index signature with a parameter of type 'string' was found on type 'unknown'.

关于第二个功能:

idsArray.push(obj.id)

TS2339: Property 'id' does not exist on type 'T'.

问题是什么? 实时链接

标签: typescript

解决方案


一切都好。您声明该函数应该接受类型 T,但 TypeScript 不知道这个 T 类型是什么。当然不能指望这个 T 会有属性 id。

要解决此问题,您可以执行以下操作:

  • 创建接口:
interface IId {
    id: number;
}
  • 更改函数声明以指示 typescript 应该使用带有 id 的东西:
export const getLastId = <T extends IId>(data: Array<T>): number => {
    if (Array.isArray(data) && data.length > 0) {
        // Create an array of Id's of all items
        const idsArray: number[] = [];
        data.forEach((obj) => {
            idsArray.push(obj.id);
        });
        // Return last element id
        return idsArray[data.length - 1];
    } else {
        return 1;
    }
};

现在一切都会好起来的。

升级版:

取决于 TS 版本错误

返回 obj[key] === val;

仍有可能发生。要解决此问题,您至少有两个选择:

再声明一个接口:

interface IIndexer {
    [key: string]: any;
}

并再次重新声明函数:

export const matchStr = <T extends IId & IIndexer>(key: string, val: string, data: Array<T>): string => {

或将 obj 强制转换为函数内部的任何内容

const result = data.find((obj: any) => obj[key] === val;);

最后一个选项更简单,但它不是类型安全的,所以我不推荐它,因为代码应该是可维护的

希望这可以帮助。


推荐阅读