如何在 Typescript 中使用泛型动态设置特定类型的值

假设我有一个通用实用程序类,它应该与一个类接口,并且有一个方法 setPropertiesToTrue,它接受一个类属性列表,并将类实例中的这些属性设置为 true。

class SomeObject{
  x: boolean 
  y: boolean
  z: string

  constructor(x: boolean,y: boolean,z: string){
    this.x = x,
    this.y = y,
    this.z = z
  } 
}

class ProperySetter<TSomeObject>{
  objectContext: TSomeObject

  constructor(objectContext: TSomeObject){
    this.objectContext = objectContext
  }

  setPropertiesToTrue(properties: Array<keyof TSomeObject>){
    properties.forEach(property => {
      this.objectContext[property] = true
    })
  }
}


const someObject = new SomeObject(false, false, "hello")

const propertySetter = new ProperySetter(someObject);

propertySetter.setPropertiesToTrue(["x", "y"])

console.log(someObject.x) // changed from false to true
console.log(someObject.y) // changed from false to true
console.log(someObject.z) // unchanged


是我正在尝试做的或多或少的 TS Playground 示例。

在上面的示例中,(在操场上的第 22 行),打字稿似乎不知道作为属性传递的键对应于 generic 内的布尔值TSomeObject所以我得到了错误:

类型 'boolean' 不可分配给类型 'TSomeObject[keyof TSomeObject]'。

这是有道理的,因为keyof TSomeObject对应于 TSomeObject 的所有键,而不仅仅是对应于布尔键的键。

有没有办法解决这个问题?

sno2

您可以加强输入数组的约束以仅包含作为boolean值的键。但是,TS 不够聪明,无法知道密钥在数组中是否有效。因此,您将只需要使用演员表即可使代码正常工作。这是一个对键类型有更好约束的工作代码示例:

class SomeObject{
  x: boolean 
  y: boolean
  z: string

  constructor(x: boolean, y: boolean, z: string){
    this.x = x,
    this.y = y,
    this.z = z
  } 
}

class ProperySetter<TSomeObject>{
  objectContext: TSomeObject

  constructor(objectContext: TSomeObject){
    this.objectContext = objectContext
  }

  setPropertiesToTrue(properties: Array<keyof { [K in keyof TSomeObject as TSomeObject[K] extends boolean ? K : never]: 0 }>){
    properties.forEach(property => {
      (this.objectContext as any)[property] = true
    })
  }
}


const someObj = new SomeObject(true, true, "hey");
const setter = new ProperySetter(someObj);
setter.setPropertiesToTrue(["x", "y"])

// @ts-expect-error not a boolean property
setter.setPropertiesToTrue(["z"]);

TypeScript Playground 链接

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在TypeScript中使用泛型在重载函数中进行类型转换

如何在TypeScript中使用泛型类型初始化对象?

如何在TypeScript中使用泛型检测类实例

如何在TypeScript中为特定类型的泛型类型创建扩展方法

[Typescript]:如何在类型中使用命名空间值?

如何在Typescript泛型中获取数组类型

如何在 TypeScript 中转换或更改泛型类型?

如何在 TypeScript 中实例化泛型类型?

如何在 TypeScript 中获取类的泛型类型

如何在 TypeScript 中将泛型类型提示为参数?

如何在 Typescript 函数接口中约束泛型类型?

如何在TypeScript中返回泛型类型

如何在TypeScript中使用导出类型?

如何在TypeScript中使类泛型成为可选

如何在TypeScript中使用“ then”?

如何使用受约束的泛型值类型在 TypeScript 中创建对象?

如何在Arrow函数中使用Typescript泛型添加两个参数

如何在TypeScript中使用泛型抽象Redux的connect方法?

如何在函数调用中使用Typescript泛型类构造函数作为参数

如何在TypeScript中使用泛型为记录建立索引?

如何在Flow中使用相同泛型类型的值对泛型函数进行类型检查

如何在TypeScript的泛型函数中使用有界类型?

如何使用精确的泛型类型制作 Typescript Reducer

在 TypeScript 中,如何使用泛型提取类实例类型?

当结构是动态的(未知)时,如何在 Typescript 中设置类型?

如何在 TypeScript 中为泛型类型编写泛型辅助函数?

如何在TypeScript中为动态“ this”值定义类型?

如何在Typescript中使Promise类型安全?

如何使泛型对象使用在Typescript中使用一个类型或void的两个函数的函数参数