gpt4 book ai didi

typescript - 字符串不能用于索引类型 'T'

转载 作者:行者123 更新时间:2023-12-04 00:54:21 30 4
gpt4 key购买 nike

我在 TypeScript 中使用了严格模式,并且在为对象设置索引时遇到了问题,即使我已经在其类型上设置了字符串索引器。
禁用 noImplicitAny 可以修复它,但我宁愿不这样做。
我学过this仔细回答但没有成功的建议。

type stringKeyed = { [key: string]: any }
type dog = stringKeyed & { name: string }
type cat = stringKeyed & { lives: number }

function setLayerProps<T extends dog | cat>(
item: T,
props: Partial<T>
) {
if (item) {
Object.entries(props).forEach(([k, v]) => {
item[k] = v; // Error: Type 'string' cannot be used to index type 'T'.ts(2536)

});
}
}


let d = { name: 'fido' } as dog;
let c = { lives: 9 } as cat;
setLayerProps(d, { name: 'jim' })
setLayerProps(c, { lives: --c.lives })
谁能看到我做错了什么?
谢谢!

最佳答案

这是#30769的效果和已知的重大变化。我们以前允许这样疯狂的事情没有错误:

function foo<T extends Record<string, any>>(obj: T) {
obj["s"] = 123;
obj["n"] = "hello";
}
let z = { n: 1, s: "abc" };
foo(z);
foo([1, 2, 3]);
foo(new Error("wat"));
通常,约束 Record 实际上并不确保参数具有字符串索引签名,它只是确保参数的属性可分配给类型 XXX。因此,在上面的示例中,您可以有效地传递任何对象,并且该函数可以在不进行任何检查的情况下写入任何属性。
在 3.5 中,我们强制您只能在我们知道所讨论的对象具有索引签名时才能写入索引签名元素。所以,你需要对 clone 函数做一个小改动:
function clone<T extends Record<string, any>>(obj: T): T {
const objectClone = {} as Record<string, any>;

for (const prop of Reflect.ownKeys(obj).filter(isString)) {
objectClone[prop] = obj[prop];
}

return objectClone as T;
}
通过此更改,我们现在知道 objectClone 具有字符串索引签名。
所以你的代码应该是
function setLayerProps<T extends dog | cat>(
item: T,
props: Partial<T>
) {
if (item) {
Object.entries(props).forEach(([k, v]) => {
(item as dog | cat)[k] = v;

});
}
}
引用: https://github.com/microsoft/TypeScript/issues/31661#issuecomment-497138929

关于typescript - 字符串不能用于索引类型 'T',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63893394/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com