[英]How to express a generic constraint to have a dynamic property of a specific type
我正在構建一個提供通用實用程序 function 的庫。
這個 function 應該對傳入的 object 的屬性之一做一些事情,但屬性名稱也是用戶提供的參數。
為了簡化,想象一下:
type T1 = {
id: string;
foo: number;
bar: string[];
}
const sampleData1: T1 = { bar: ["a"], foo: 42, id: "myid" }
const doSomething = <F>(somearg: F, path: keyof F) => {
console.log(somearg[path]);
}
doSomething(sampleData1, "id");
output 是我所期望的: "myid"
。
但是,我只想在我的 function 中使用字符串。 但實際代碼也適用於:
type T3 = {
wrong: number;
value: number;
}
const sampleData3 : T3 = { value : 100, wrong : 5 }
const doSomething = <F>(somearg: F, path: keyof F) => {
console.log(somearg[path]);
}
doSomething(sampleData3, "wrong");
此代碼有效並發出5
。 但我實際的 function 應該只適用於字符串。
有沒有辦法表達F
泛型類型以使動態名稱屬性只是一個字符串?
我試過了:
const doSomething = <F extends { [path] : string }>(somearg: F, path: keyof F) => {
console.log(somearg[path]);
}
但語法無效:
A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
Cannot find name 'path'.
如何解決?
僅供參考:我運行 TS 4.5.5。 我實際的 function 處於依賴關系中,並且消費代碼存在於多個應用程序中,具有非常不同的業務需求。
實用程序 function 也可以在同一個 object 上調用多次,但屬性名稱不同。
在這種情況下,索引 object 類型的語法是{ [key in KeyType]: valueType }
。
在您的情況下,您希望約束F
以使路徑具有字符串值,但您不關心 rest。
您可以使用 2 種通用類型:1 用於路徑,1 用於 object:
const doSomething = <P extends string, F extends { [p in P]: string }>(somearg: F, path: P) => {}
它正確拒絕了第三個樣本:
doSomething(sampleData1, "id");
doSomething(sampleData2, "key");
doSomething(sampleData3, "wrong"); // Error: Type 'number' is not assignable to type 'string'.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.