我试图在数组原型中添加一些功能,无法使其按预期工作。
interface Array<T> {
getBy: T extends object ? <P extends keyof T>(value: T[P], prop: P) => T | null : (value: T) => T | null;
}
Array.prototype.getBy = getType;
function getType<T>(this: T[], value: T): T | null
function getType<T extends object, P extends keyof T>(this: T[], value: T[P], prop: P): T | null
function getType<T, P extends keyof T>(this: T[], value: T | T[P], prop?: P, ) {
if (prop) {
return this.filter(item => item[prop] === value)[0] || null;
} else {
return this.filter(item => item === value)[0]
}
};
const someArray = [{ a: 1 }, { a: 2 }, { a: 3 }];
const complexArray = [{ a: 1, b: 200 }, { a: 2 }, { a: 3 }];
const primArray = [1, 2, 3];
console.log(primArray.getBy(1));
console.log(someArray.getBy(3, 'a'));
// console.log(complexArray.getBy(200, 'a')); Throws error.
答案 0 :(得分:1)
问题是complexArray
具有联合类型。在联合类型上使用条件类型时,条件类型将分布在联合的成员上。因此,getBy
最终将是函数签名的并集,根据定义,它们是不可调用的。
最简单的解决方案是不使用条件类型,在这种情况下,重载会更好地工作:
interface Array<T> {
getBy<T>(this: T[], value: T): T | null
getBy<T extends object, P extends keyof T>(this: T[], value: T[P], prop: P): T | null
}
Array.prototype.getBy = getType;
function getType<T>(this: T[], value: T): T | null
function getType<T extends object, P extends keyof T>(this: T[], value: T[P], prop: P): T | null
function getType<T, P extends keyof T>(this: T[], value: T | T[P], prop?: P, ) {
if (prop) {
return this.filter(item => item[prop] === value)[0] || null;
} else {
return this.filter(item => item === value)[0]
}
};
const someArray = [{ a: 1 }, { a: 2 }, { a: 3 }];
const complexArray = [{ a: 1, b: 200 }, { a: 2 }, { a: 3 }];
const primArray = [1, 2, 3];
console.log(primArray.getBy(1));
console.log(someArray.getBy(3, 'a'));
console.log(complexArray.getBy(200, 'a'));