访问泛型类型中的成员

Accessing members inside generic types

我有一个功能,之前实现如下

export function insertItemInQueue(
  queueRef: RefObject<Partial<IMyRow>[]>,
  item: Partial<IMyRow>
) {
    console.log(item.ID)
    queueRef.current.push(item);
}

为了使用泛型,我改成了

export function insertItemInQueue<ItemType>(
  queueRef: RefObject<ItemType[]>,
  item: ItemType
) {
     console.log(item.ID)
     queueRef.current.push(item);
}

但是,我现在收到 TS 错误:属性 'ID' 在类型 'ItemType' 上不存在。

我知道 ItemType 可以是任何东西,可能并不总是将 ID 作为其成员。我们如何解决这个问题?

我能够通过将它用作 item['ID'] 而不是 item.ID 来编译它。但我不确定这是否可以?我觉得它带走了泛型的意义,并且强烈依赖于这样一个事实,即无论传入什么泛型类型,都必须包含一个名为 ID 的成员,这不是真正的泛型?

如果您想在 compile-time 强制此函数调用只接受具有 ID 属性 的类型,您可以将泛型类型定义为从一个对象扩展包含一个 ID 属性,像这样(如果你的 ID 不是 number,只需调整示例)

function insertItemInQueue<ItemType extends { ID: number }>(
  queueRef: RefObject<ItemType[]>,
  item: ItemType
) {
    console.log(item.ID) // no more compiler error
    queueRef.current.push(item);
}

然后编译器在调用点检查并强制执行类型

insertItemInQueue(queue, { ID: 123 }) // OK
insertItemInQueue(queue, { ID: 123, a: 1, b: "Some text" }) // OK

insertItemInQueue(queue, { ID: null }) // Error: Type 'null' is not assignable to type number
insertItemInQueue(queue, { ID: undefined }) // Error: Type 'undefined' is not assignable to type number
insertItemInQueue(queue, { a: 1 }) // Error: not the right type because the ID property is missing