typescript - Standardtyp av keyof T kan inte användas för att indexera typ T
Jag försöker refaktorera denna kod för att använda statisk metod eftersom klassen endast används som ett namnrymd och Query.equal<TodoModel>(...) är bättre än (new Query<TodoModel>).equal(...)
interface TodoModel {
title: string;
timeLeft: number;
done: boolean;
}
class Query<T> {
equal<K extends keyof T>(attr: K, val: T[K]) {
return `${String(attr)}==${val}`;
}
// other methods for notEqual, lessThan, greaterThan, contains etc.
}
let q = (new Query<TodoModel>)
q.equal("unknownKey", 45) // unknownKey gives error
q.equal("title", 765) // 765 is the wrong type
q.equal("title", "write notes") // no errors
Jag försökte:
class Query2 {
static equal<T, K = keyof T>(attr: K, val: T[K]) {
return `${String(attr)}==${val}`;
}
}
Detta ger mig ett felmeddelande som säger att K inte kan användas för att indexera T. Varför skulle det vara så och finns det en lösning på detta?
Jag använder standardtyp eftersom med extends (equal<T, K extends keyof T>) skulle användningen vara Query2.equal<TodoModel, "title">("title", "write notes") där nyckeln behöver upprepas.
Här är hela TypeScript-lekplatsen: Länk till lekplatsen
Svar #1
Om du endast vill nämna modellen och inte typen, är den möjliga lösningen att ha en union av alla möjliga nyckel-värde-par, vilket kan uppnås med följande typ:
type UnionArgs<T> = {
[K in keyof T]: [K, T[K]];
}[keyof T];
Användning :
// ["title", string] | ["timeLeft", number] | ["done", boolean]
type Result = UnionArgs<TodoModel>
Det enda som återstår är att uppdatera metoden/funktionen på följande sätt:
function queryEqual<T>(...args: UnionArgs<T>) {
return `${String(args[0])}==${args[1]}`;
}
lekplats
