typescript - 以任何对象的数组为参数的通用函数
问题描述
我创建了 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'.
问题是什么? 实时链接。
解决方案
一切都好。您声明该函数应该接受类型 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;);
最后一个选项更简单,但它不是类型安全的,所以我不推荐它,因为代码应该是可维护的
希望这可以帮助。
推荐阅读
- crystal-reports - 如何将每个详细信息部分的值存储在单独的变量中?
- android - Xamarin 资源文件等效项
- python - ValueError:对象太深,无法在 optimize.curve_fit 中找到所需数组
- python - 将数据框复制到具有默认值的列的 postgres 表
- html - HTML 输入删除最后一个字符的字母间距
- arrays - R - 包含逗号分隔值数组的数据框
- velocity - Apache Velocity #解析一个文件,如果它存在
- asp.net - asp.net 页面随机丢失所有表单数据并且不回发
- python - pymongo - 将字典附加到列表中不起作用
- amazon-web-services - CloudFront 签名 URL 中断客户端缓存