简体   繁体   English

Typescript typeof 对象中的值

[英]Typescript typeof value in an object

Trying to strongly type a data formatting function.试图强类型数据格式化函数。 What function does is simple,功能很简单,

Input:输入:

 const eleOfArray = { a: 1, b: "string", c: [1, 2, 3] }

Output:输出:

 const eleOfArray = { a: { value: 1, component: 1 }, b: { value: "string", component: "string" }, c: { value: [1, 2, 3], component: [1, 2, 3] } }

function:功能:

 export function tableDataFormatter<T>(d: T) { const formatedData: ITableData<T> = {} Object.keys(d).forEach((key: string) => { // tslint:disable-next-line:ban-ts-ignore // @ts-ignore formatedData[key] = { // tslint:disable-next-line:ban-ts-ignore // @ts-ignore value: d[key as keyof T], component: d[key as keyof T] } }) return formatedData }

Interface:界面:

 interface ITableData<T> { readonly [key: keyof T]: { readonly component: React.ReactNode readonly value: T[keyof T] } }

The problem I'm having with this code is when I use tableDataFormatter it shows value is always string | number我在使用此代码时遇到的问题是,当我使用tableDataFormatter它显示value始终为string | number string | number . string | number

Usage:用法:

 public formatData<IBenefit> (data: ReadonlyArray<IBenefit>): ReadonlyArray<ITableData<IBenefit>> { return super.formatData(data).map((d: ITableData<IBenefit>) => ({ ...d, stores: { ...d.stores, component: <Addon addonValues={d.stores.value} /> // d.stores.value should be an Array but it's being shown as ReactText/string } })) }

So I have to suppress the err cause the function is working as intended and I'm clearly assigning value as readonly value: T[keyof T]所以我必须抑制错误,因为函数按预期工作,我清楚地将value分配为readonly value: T[keyof T]

Your ITableData<T> interface is not valid TypeScript.您的ITableData<T>接口不是有效的 TypeScript。 Specifically, you are trying to use an index signature constrained to keyof T , but the only allowable index signature types are string and number .具体来说,您正在尝试使用限制为keyof T索引签名,但唯一允许的索引签名类型是stringnumber Instead you should consider using a mapped type instead of an interface.相反,您应该考虑使用映射类型而不是接口。 It will give you the mapping you want:它会给你你想要的映射:

type ITableData<T> = {
  readonly [K in keyof T]: {
    readonly component: React.ReactNode
    readonly value: T[K]
  }
}

Note how the nested value property is of type T[K] and not T[keyof T] .请注意嵌套value属性的类型是T[K]而不是T[keyof T] T[keyof T] is going to be the union of all value types of T and the mapping from each key to each value is lost. T[keyof T]将是的所有值类型的联合T并且从每个键的每个值映射丢失。 But T[K] means that for each key K , the nested value property is of the same type as the original property of T indexed by K .但是T[K]意味着对于每个键K ,嵌套的value属性与由K索引的T的原始属性具有相同的类型。 This is the way to avoid the string | number这是避免string | number string | number problem. string | number问题。

Then for tableDataFormatter() I'd change some of the annotations and assertions like follows:然后对于tableDataFormatter()我会更改一些注释和断言,如下所示:

// strip off the readonly modifier for the top level properties
type Mutable<T> = { -readonly [K in keyof T]: T[K] };

// explicitly declare that the function returns ITableData<T>
export function tableDataFormatter<T extends Record<keyof T, React.ReactNode>>(
  d: T
): ITableData<T> {

  // assert that the return value will be ITableData<T> but make it
  // mutable so we can assign to it in the function without error
  const formatedData = {} as Mutable<ITableData<T>>;

  // assert that Object.keys(d) returns an array of keyof T types
  // this is not generally safe but is the same as your "as keyof T"
  // assertions and only needs to be done once.
  (Object.keys(d) as Array<keyof T>).forEach(key => {
    formatedData[key] = {
      value: d[key],
      component: d[key]
    }
  })

  return formatedData
}

Hopefully that works the way you expect now.希望它以您现在期望的方式工作。 Good luck!祝你好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 JavaScript 中将对象中所有元素的类型(typeof)分配给变量 | 打字稿? - How to assign types of (typeof) all elements in the object to a variable in JavaScript | Typescript? TypeScript typeof泛型类的类型 - TypeScript typeof type of generic class typescript 中有/无 typeof 的区别 - difference between with/without typeof in typescript (React Typescript)“组件”指的是一个值,但在这里被用作一个类型。 您的意思是“typeof 组件”吗? - (React Typescript) 'Component' refers to a value, but is being used as a type here. Did you mean 'typeof Component'? TypeScript object 中键值的类型 - TypeScript type for value of key in object 如何改变typescript中的object的值? - How to change the object value in typescript? Typescript typeof React.Component的子类 - typescript typeof subclass of React.Component React typescript 条件渲染类型日期 - React typescript conditional rendering typeof Date 如何使 typeof typescript 中的类型可选 - How to make type optional in typeof typescript Typescript + React 测试库 - 'SidebarItem' 指的是一个值,但在这里用作类型。 您的意思是“typeof SidebarItem”吗?ts(2749) - Typescript + React Testing Library - 'SidebarItem' refers to a value, but is being used as a type here. Did you mean 'typeof SidebarItem'?ts(2749)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM