我正在尝试将eachr包转换为TypeScript。
这是所需的用法:
const obj = { a: 1, b: 'str' }
iterateObject(obj, function(value, key) {
if (key === 'a') console.log(value) // intellisense should know value is a number
if (key === 'b') console.log(value) // intellisense should know value is a string
})
这是当前的实现:
interface IteratorCallback<Subject, Key, Value> {
(this: Subject, value: Value, key: Key, subject: Subject): void | false
}
function iterateObject<
Subject extends object,
Key extends keyof Subject,
Value extends Subject[Key]
>(subject: Subject, callback: IteratorCallback<Subject, Key, Value>): Subject {
for (const key in subject) {
if (subject.hasOwnProperty(key)) {
const value = subject[key]
if (callback.call(subject, value, key, subject) === false) {
break
}
}
}
return subject
}
但是,有以下抱怨:
[ts] 类型'Subject [Extract]'的参数不能分配给'值'类型的参数。 类型“ object [Extract]”不可分配给“值”类型。 [2345]
如果我也更改了通用名称:
function iterateObject<
Subject extends Record<Key, Value>,
Key extends Extract<keyof Subject, string>,
Value extends Subject[Key]
>
然后我收到以下投诉:
[ts] 类型“提取”的参数不能分配给类型“键”的参数。 类型'string&keyof Subject'不能分配给类型'Key'。 类型“字符串”不可分配给类型“键”。 类型“字符串”不可分配给类型“键”。 [2345]
我可以将其更改为此:
export function iterateObject<Key extends keyof any, Value>(
subject: Record<Key, Value>,
callback: IteratorCallback<typeof subject, Key, Value>
): typeof subject {
哪一个没有错,并创造了价值string | number
,但是我不确定为什么它会起作用,而其他人却没有,也不知道为什么{{1}时它无法弄清楚},那么key === 'a'
应该是value
。
我在这里想念什么?