将 Array.prototype.includes() 替换为不 return 布尔值的方法
Replace Array.prototype.includes() with a method that does not return a boolean
我在 Typescript 中有一个函数,其中,从字符串中,它 return 是包含该变量的对象的键。
我正在使用 Array.prototype.includes()
检查变量是否存在,这可以 return true
或 false
,因此将结果变量键入 [=17] =] 给我打字错误。
这是错误:
Type 'unknown' cannot be assigned to type 'string'
这是我的功能:
let testData = {
data1: ['CAR','PLANE'],
data2: ['COUNTRY','CITY']
};
let asset = 'car';
function resKey(asset) {
let res = Object.keys(testData).find(key => {
const value = testData[key]
return value.includes(asset.toUpperCase())
})
return res
}
console.log(resKey(asset));
我只会将对象中的值传递给它,因此我不需要检查它是否存在。
我的问题:我如何修改函数,使其只 return 键而不需要检查它是否存在?
正如我在评论中指出的那样,您可以通过为当前函数提供一些类型注释来使其对 Typescript 友好。
或者,您可以通过创建 testData
的 Map
并直接通过 value
检索 key
来避免 find()
。请记住,如果不同资产数组之间存在重复值,这将 return 最后一个实例的键(与 find()
将 return 第一个实例的键相反)。
let testData = {
data1: ['CAR', 'PLANE'],
data2: ['COUNTRY', 'CITY']
};
let asset = 'car';
function resKey(asset) {
const resMap = new Map(Object.entries(testData).flatMap(([k, v]) => v.map(a => [a, k])));
return resMap.get(asset.toUpperCase());
}
console.log(resKey(asset));
为避免在每次调用函数时都创建一个新的 Map
,您可以使用一点柯里化。
function resKeyFactory(data) {
const resMap = new Map(
Object.entries(data)
.flatMap(([k, v]) => v.map(a => [a, k]))
);
return (asset) => resMap.get(asset.toUpperCase());
}
const
testData = {
data1: ['CAR', 'PLANE'],
data2: ['COUNTRY', 'CITY']
},
asset = 'car',
resKeyTestData = resKeyFactory(testData);
console.log(resKeyTestData(asset));
console.log(resKeyTestData('city'));
Typescript 需要足够高的目标才能接受 flatMap
playground.
您可以使用 Object.entries()
和 find()
。
let testData = {
data1: ['CAR', 'PLANE'],
data2: ['COUNTRY', 'CITY']
};
function resKey(data, asset) {
return Object.entries(data).find(([_, v]) => {
return v.includes(asset.toUpperCase())
})?.[0] || "no key found";
}
console.log(resKey(testData, "car"));
console.log(resKey(testData, "something"));
console.log(resKey(testData, "city"));
如果你想打字,它看起来像这样。
interface IData {
data1: string[];
data2: string[];
}
let testData: IData = {
data1: ['CAR', 'PLANE'],
data2: ['COUNTRY', 'CITY']
};
function resKey(data: IData, asset: string): string {
return Object.entries(data).find(([_, v]) => {
return v.includes(asset.toUpperCase())
})?.[0] || "no key found";
}
我在 Typescript 中有一个函数,其中,从字符串中,它 return 是包含该变量的对象的键。
我正在使用 Array.prototype.includes()
检查变量是否存在,这可以 return true
或 false
,因此将结果变量键入 [=17] =] 给我打字错误。
这是错误:
Type 'unknown' cannot be assigned to type 'string'
这是我的功能:
let testData = {
data1: ['CAR','PLANE'],
data2: ['COUNTRY','CITY']
};
let asset = 'car';
function resKey(asset) {
let res = Object.keys(testData).find(key => {
const value = testData[key]
return value.includes(asset.toUpperCase())
})
return res
}
console.log(resKey(asset));
我只会将对象中的值传递给它,因此我不需要检查它是否存在。
我的问题:我如何修改函数,使其只 return 键而不需要检查它是否存在?
正如我在评论中指出的那样,您可以通过为当前函数提供一些类型注释来使其对 Typescript 友好。
或者,您可以通过创建 testData
的 Map
并直接通过 value
检索 key
来避免 find()
。请记住,如果不同资产数组之间存在重复值,这将 return 最后一个实例的键(与 find()
将 return 第一个实例的键相反)。
let testData = {
data1: ['CAR', 'PLANE'],
data2: ['COUNTRY', 'CITY']
};
let asset = 'car';
function resKey(asset) {
const resMap = new Map(Object.entries(testData).flatMap(([k, v]) => v.map(a => [a, k])));
return resMap.get(asset.toUpperCase());
}
console.log(resKey(asset));
为避免在每次调用函数时都创建一个新的 Map
,您可以使用一点柯里化。
function resKeyFactory(data) {
const resMap = new Map(
Object.entries(data)
.flatMap(([k, v]) => v.map(a => [a, k]))
);
return (asset) => resMap.get(asset.toUpperCase());
}
const
testData = {
data1: ['CAR', 'PLANE'],
data2: ['COUNTRY', 'CITY']
},
asset = 'car',
resKeyTestData = resKeyFactory(testData);
console.log(resKeyTestData(asset));
console.log(resKeyTestData('city'));
Typescript 需要足够高的目标才能接受 flatMap
playground.
您可以使用 Object.entries()
和 find()
。
let testData = {
data1: ['CAR', 'PLANE'],
data2: ['COUNTRY', 'CITY']
};
function resKey(data, asset) {
return Object.entries(data).find(([_, v]) => {
return v.includes(asset.toUpperCase())
})?.[0] || "no key found";
}
console.log(resKey(testData, "car"));
console.log(resKey(testData, "something"));
console.log(resKey(testData, "city"));
如果你想打字,它看起来像这样。
interface IData {
data1: string[];
data2: string[];
}
let testData: IData = {
data1: ['CAR', 'PLANE'],
data2: ['COUNTRY', 'CITY']
};
function resKey(data: IData, asset: string): string {
return Object.entries(data).find(([_, v]) => {
return v.includes(asset.toUpperCase())
})?.[0] || "no key found";
}