如何将类型对象键转换为打字稿中的字符串数组

时间:2020-05-01 06:16:31

标签: typescript

在打字稿中提供了以下输入内容:

type InputObjectType = {
  a: string
  b: number
  c: {}
}

如何获取以下类型:

type ObjectKeysArrayType = ['a', 'b', 'c']

到目前为止,我只能做到:

type AllPossibleKeys = (keyof InputObjectType)[]

这给了我["a" | "b" | "c"]很近,但不是我在这种情况下要寻找的东西。

我需要一个始终包含给定类型对象中所有键字符串的数组。我知道强制执行此操作的唯一方法,例如,当用户将新键添加到对象(该键也添加到数组中)时,就是通过这种方式实现的。

4 个答案:

答案 0 :(得分:0)

当前不可能,因为类型信息在运行时不可用。您可以在Typescript Playground上尝试使用您的代码。当您这样做时,您会发现以下代码:

type InputObjectType = {
  a: string
  b: number
  c: {}
}

被翻译成空。在将代码转换为javascript之后,它根本不存在。由于它在运行时不存在,因此无法执行任何运行时操作,例如遍历其属性,甚至将其打印出来。

答案 1 :(得分:0)

不确定您是否仍在这里寻找解决方案,但希望这会有所帮助。

如果您想要的是一种类型,要求变量是仅包含等于对象键值的字符串数组,那么您列出的内容应该起作用。

type InputObjectType = {
  a: string
  b: number
  c: {}
}

type AllPossibleKeys = (keyof InputObjectType)[]

AllPossibleKeys的类型将等于("a"|"b"|"c")[]。这似乎是您所要的,但我想知道您想如何使用它。

const fieldArray1: AllPossibleKeys = ['a', 'b', 'c']; //valid
const fieldArray2: AllPossibleKeys = ['a', 'b', 'c', 'd']; //will throw a Typescript error
const fieldArray3: AllPossibleKeys = ['a', 'b']; //this is also valid though as each member is a valid value

如果您想要一个类型中的所有键组成的数组,那么我所知道的没有一种方法可以明确地执行此操作。但是,如果您能够使用接口而不是类型,则可以执行以下操作:

import { keys } from 'lodash';

interface InputObject = {
  a: string
  b: number
  c: {}
}

class InputObjectStub implements InputObject {
  a = null;
  b = null;
  c = null;
}

const fieldArray1 = keys(new InputObjectStub()); //returns ['a', 'b', 'c']

但是请注意,这不会强制执行可选属性。如果需要这样做,请将您的类定义更改为class InputObjectStub implements Required<InputObject> {...

编辑:拼写

答案 2 :(得分:0)

我使用两种方法:

// Option 0: Define type using object
const someTypeExample = {
  a: 1,
  b: 'str',
  c: 'foo' as 'foo'|'bar'
};

type SomeType0 = typeof someTypeExample;


// Option 1: If object stores different types
type SomeType = {
  a: number;
  b: string;
}

const typeVar: SomeType = {
    a: 10,
    b: 'string'
}

// used for typechecking
type SomeTypeKey = keyof SomeType;

// create an array to be used in runtime
// disadvantage is that properties need to be repeated
const keys: SomeTypeKey[] = ['a', 'b']; // type checked
// TODO what I'm missing is:
// const keys = keys<SomeTypeKey>(); that would return ['a', 'b'] during transpiling
// ie. native support of https://github.com/kimamula/ts-transformer-keys 
// which is out of scope for TS: https://github.com/microsoft/TypeScript/issues/13267
let isValidKey = keys.includes('c' as SomeTypeKey)


// Option 2: start from keys array definition, in case all values have the same type

const myKeys = ['foo', 'bar'] as const; // as const does the magic
type MyKey = typeof myKeys[number]; // = 'foo' | 'bar'

type MyMap = Record<MyKey, string>;
type MyMap2 = { [key in MyKey]: string };

答案 3 :(得分:-1)

尝试

req.url.match(/\/auth\/([^\/]+)/)