Typescript:如何提取 const 对象的值类型并将它们用作新类型中的键?

问题描述 投票:0回答:3

我想获取一个常量对象,例如

{key1: 'value1', key2: value2'} as const
,并将其值转换为键,并在类型为
{value1: number; value2: number}
的新对象中使用它。我想在一个函数中执行此操作,并且我希望该函数能够正确键入。

下面是我试图开始工作的代码。当我尝试将

Partial<Blah>
类型的变量转换为
Blah
时,会发生错误。有人可以解释为什么会发生这种情况,以及是否有办法做我想做的事情?谢谢!

type BaseObject = Record<string, string>;


type ValuesAsKeys<T extends BaseObject> = {
    [K in keyof T as T[K]]: number;
};

function useValuesAsKeys<T extends BaseObject>(arg: T): ValuesAsKeys<T> {
  const x: Partial<ValuesAsKeys<T>> = {};
  for (const value of Object.values(arg) as Array<T[keyof T]>) {
    x[value] = 1;
  }

  // This line doesn't work
  return x as ValuesAsKeys<T>;
}

// Example use case
const obj = {key1: 'value1', key2: 'value2'} as const;
const result = useValuesAsKeys(obj); // Type of result is {value1: number; value2: number}


// Everything below here works
// Only including this because I'm contrasting this code with the code above.

type KeysAsKeys<T extends BaseObject> = {
    [K in keyof T]: number;
};

function useKeysAsKeys<T extends BaseObject>(arg: T): KeysAsKeys<T> {
    const x: Partial<KeysAsKeys<T>> = {};
  for (const value of Object.values(arg) as Array<T[keyof T]>) {
    x[value] = 1;
  }
  return x as KeysAsKeys<T>;
}
typescript generics types partial
3个回答
1
投票

带有

reduce
的显式返回类型几乎总是不起作用,因为
initial
值每次迭代都会发生变化。

为了使其工作,最好重载你的函数:

type BaseObject = Record<string, string>;


type ValuesAsKeys<T extends BaseObject> = {
  [K in keyof T as T[K]]: number;
};

type Values<T> = T[keyof T]

function useValuesAsKeys<T extends BaseObject>(arg: T): ValuesAsKeys<T>
function useValuesAsKeys<T extends BaseObject>(arg: T) {
  return (Object.values(arg) as Array<Values<T>>).reduce((acc, elem) => ({
    ...acc,
    [elem]: 1
  }), {})
}

// Example use case
const obj = { key1: 'value1', key2: 'value2' } as const;

const result = useValuesAsKeys(obj); // Type of result is {value1: number; value2: number}
result.value1 //ok

游乐场

文档


0
投票

我仍然不确定为什么将

Partial<Blah>
转换为
Blah
在这种情况下不起作用,但这段代码可以工作并且对我来说足够类型安全:

function useValuesAsKeys<T extends BaseObject>(arg: T): ValuesAsKeys<T> {
  const x = {} as ValuesAsKeys<T>;
  for (const value of Object.values(arg) as Array<T[keyof T]>) {
    x[value] = 1;
  }
  return x;
}

0
投票

有一种更简单的方法可以实现这一点。

const obj = {key1: 'value1', key2: 'value2'} as const;

type ValuesAsKeys = typeof obj[keyof typeof obj];

const myUseOfObject: { [ValuesAsKeys 中的键]: number} = { 值1:1, 值2:2 }

© www.soinside.com 2019 - 2024. All rights reserved.