简体   繁体   中英

Typescript interface from array type

I need to force an array to have a specific set of values that should be then the keys of my interface. I can force the array with

type SomeProperties = ['prop1', 'prop2', 'prop3'];

but I don't know how to force an interface to have those properties. I tried something like

type MyInterface = {
  [key in keyof SomeProperties]: string;
}

but obviously the keys of an array are just numbers so my interface become

interface MyInterface {
  0: string;
  1: string;
  2: string;
}

instead of the wanted interface

interface MyInterface {
  prop1: string;
  prop2: string;
  prop3: string;
}

Do you know if there is a way to achieve this in Typescript?

It would be useful because I need to iterate on some properties to "clone" an object and I also need to access to those properties easily. Repeating the properties in both type and interface is a bit fragile for me.

Worth noting: You can't iterate an tuple type in TypeScript

Actually, you can! Since TypeScript 3.1 you can safely use tuple types in mapped types like objects .

These sorts of operations can only be applied to type s, not interface s.

type SomeProperties = 'prop1' | 'prop2' | 'prop3';

type MyType = Record<SomeProperties, string>;

// equivalent to
// type MyType = {
//   [key in SomeProperties]: string
// }

Types and interface are the same from the perspective of the consumer (when you ask for a MyType , you don't care if it's an interface or a type, they're the same at that point)

As you note, the strings you're trying to access aren't the keys of SomeProperties , but the elements of SomeProperties .

You can use the indexed access operator here: if K is a key (or a union of keys) of T , then T[K] is the property type (or union of property types) corresponding to accessing the K key(s) of T .

Tuples and arrays accept number as a key type, so you want to use SomeProperties[number] to give you the union "prop1"|"prop2"|"prop3" :

type SomeProperties = ['prop1', 'prop2', 'prop3'];

type MyInterface = {
  [key in SomeProperties[number]]: string;
}

const myInterface: MyInterface = {
  prop1: 'this',
  prop2: 'works',
  prop3: 'now'
}

Hope that helps; good luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM