我遇到了一個問題,我通過創建下面的函式簡化了這個問題:
我遇到了一個問題。
function setProperty< T extends Record<string, string>> (obj: T, key: keyof T) {
obj[key] = "hello"。
}
代碼不能編譯,obj[key]下劃線為紅色,我得到的錯誤:
型別'string'不能被分配到型別'T[keyof T]'.ts(2322)
我明白這是因為關鍵字 "extends",但我不知道如何解決我的問題。
你能幫我解決這個問題嗎?
uj5u.com熱心網友回復:
只需使用Object.assign
type StringValue<Obj> = {
[Prop in keyof Obj] 。Obj[Prop] extends string ? Prop : never
}[keyof Obj] ?
/**。
* 獲得所有帶有字串值的鍵
*只允許使用這些鍵
*/
型別 Result = StringValue<{ age: number, name: string }> // name
function setProperty<
Value。
Obj extends Record<string, Value>
>(obj: Obj, key: StringValue<Obj>) {
Object.assign(obj, { [key]: 'hello'/span> })
}
const user = {
年齡。42,
name: 'John',
surname: 'Doe', 'Doe'.
}
setProperty(user, 'name') // ok
setProperty(user, 'surname') // ok ok
setProperty(user, 'age') //預計錯誤,因為age是一個數字。
在StringValue工具型別的幫助下,TS將只允許帶有字串值的鍵。
請嘗試在TS中避免突變。見這篇文章。
uj5u.com熱心網友回復:
根據你的使用情況,有兩種方法可以解決你的問題。如果你只是想把任何字串設定為任何特定鍵的值,你不需要使用泛型:
function setProperty(obj: Record<string, string> , key: string) {
obj[key] = "hello"。
}
然而,如果你的物件有特定的鍵和特定的值,你可以使用像這樣的泛型,這樣編譯器就會對你的引數進行型別檢查:
function setProperty<T extends Record<string, string> , K extends keyof T, V extends T[K] > (obj: T, key: K, value: V) {
obj[key] = value
}
型別 ObjectValue = 'foo' | 'bar'
型別A = {
foo: ObjectValue。
baz: 'baz'。
}
const a: A = {
foo: 'foo',
baz: 'baz'.
}
setProperty(a, 'foo'/span>, 'bar'/span>) //works
setProperty(a, 'foo', 'bar') //型別錯誤。
這也有一個很好的好處,那就是InteliSense的問題。
編輯:
由于OP只是想輸入檢查鍵并設定一個任意的字串,這個解決方案應該更好:
編輯:
既然OP只是想輸入檢查鍵并設定一個任意的字串,這個解決方案應該更好。
function setProperty< K extends string> (obj: Record<K, string>, key: K) {
obj[key] = "hello";
uj5u.com熱心網友回復:
我不確定這是否能達到你的用例所要的結果,但如果你只是想讓這個東西被編譯,你可以使用一個型別斷言。
function setProperty< T extends Record<string, string>> (obj: T, key: keyof T) {
obj[key] = "hello" as T[keyof T]。
}
"hello"具有字面型別hello。Typescript編譯器可以看到你想在obj上設定一個值,它的鍵型別為keyof T。它不能推斷出hello的型別是所需的型別,除非你像上面那樣斷言它是。
然而,如果你想將obj[key]上的值設定為hello,我個人會使用Michael Vrana答案中的第一個方法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/318607.html
標籤:
