typescript - 获取 TypeScript 中泛型类型的特定键的类型

标签 typescript generics keyof

我正在努力从我正在构建的这个 updateArray 通用函数中获得复杂的类型功能:

// Updates an object array at the specified update key with the update value,
// if the specified test key matches the test value.
// Optionally pass testFailValue to set a default value if the test fails.
// Note that by passing a testFailValue ALL elements in the array will be updated at the specified update property. 
// If it is omitted only elements passing the test will be updated.
export const updateArray = <T, U, V>(options: {
  array: Array<T>
  testKey: keyof T
  testValue: U
  updateKey: keyof T
  updateValue: V
  testFailValue?: V
}): Array<T> => {
  const {
    array,
    testKey,
    testValue,
    updateKey,
    updateValue,
    testFailValue,
  } = options
  return array.map(item => {
    if (item[testKey] === testValue) {
      item[updateKey] = updateValue
    } else if (testFailValue !== undefined) {
      item[updateKey] = testFailValue
    }
    return item
  })
}

TypeScript 会在 if 语句和两个赋值语句中提示,但在调用签名中,它不会提示,并且是我正在寻找的严格类型检查,例如:

interface IMyInterface {
    propertyA: string
    prepertyB: boolean
}

updateArray<IMyInterface, IMyInterface['propertyA'], IMyInterface['propertyB']>({
    array: state.editors[editor].editorSettings,
    testKey: "propertyA",
    testValue: 'someValue',
    updateKey: "propertyB",
    updateValue: true,
    testFailValue: false
})

如果我省略类型 UV,并将它们替换为 T[keyof T] Typescript 不会提示:

export const updateArray = <T>(options: {
  array: Array<T>
  testKey: keyof T
  testValue: T[keyof T]
  updateKey: keyof T
  updateValue: T[keyof T]
  testFailValue?: T[keyof T]
}): Array<T> => {
  const {
    array,
    testKey,
    testValue,
    updateKey,
    updateValue,
    testFailValue,
  } = options
  return array.map(item => {
    if (item[testKey] === testValue) {
      item[updateKey] = updateValue
    } else if (testFailValue !== undefined) {
      item[updateKey] = testFailValue
    }
    return item
  })
}

但这也不完全正确。 T[keyof T] 太灵活了:我可能会将“错误”类型分配给给定的属性(例如,在给定的示例中,将 bool 值分配给只应保存字符串的属性) , 或相反亦然)。显然,这种重新分配类型的行为在 JavaScript 中很好(这也是 TypeScript 不会提示的原因之一),但对于我正在制作的这个函数来说是不受欢迎的。我真正需要的是某种 typeof T[特定键],以确保 testValueupdateValuetestFailValue code> 对应于正确的类型,但特定键可以根据T的实际类型而改变。

这样的事情可以做吗?

最佳答案

您可以使用 extendsU 添加约束,使其成为 T 键的子集。 V 可以表示 updateKey 类型,并且也具有相同的约束。

将问题简化为函数 updateObject 而不是 updateArray ,它会变成:

function updateObject<
    T,
    U extends keyof T,
    V extends keyof T,
>(
    obj: T,
    testKey: U,
    testValue: T[U],
    updateKey: V,
    updateValue: T[V],
    testFailValue?: T[V]
) {
    if (obj[testKey] === testValue) {
        obj[updateKey] = updateValue;
    } else if (testFailValue !== undefined) {
        obj[updateKey] = testFailValue;
    }
}

updateObject({aString: 'hello', aNumber: 42}, 'aString', 'hello', 'aNumber', 23);

关于typescript - 获取 TypeScript 中泛型类型的特定键的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67570381/

相关文章:

html - Angular 4 显示图像

javascript - 我无法访问我的异步验证器,因为它位于 "__zone_symbol"对象中

jquery - 在 typescript 中使用 JQUERY

C# 泛型 - 类型参数的约束

javascript - MouseLeave触发 Electron 中的子元素

java - 通用列表和反射(reflection)

java - 这两个 Java 泛型方法接受相同的数据类型吗?

TypeScript:如何处理泛型类型和 keyof 运算符

typescript - 在 TypeScript 中, "extends keyof"和 "in keyof"是什么意思?

typescript - 在 TypeScript 中,如何获取值为给定类型的对象类型的键?