Amol Gupta
Amol Gupta

Reputation: 2584

Typescript - How Do I Get A Typed Array?

My Sample use case.

type someEnum = 'a' | 'b';

const someObj: { [K in someEnum]: string } = {
    a: 'a',
    b: 'b',
};

const a: Array<someEnum> = ['a', 'b'];

// In Future update someEnum

type someEnum = 'a' | 'b' | 'c';

// Gives an error;

// Property 'c' is missing in type '{ a: string; b: string; }' 
// but required in type '{ a: string; b: string; c: string; }'.

const someObj: { [K in someEnum]: string } = {
    a: 'a',
    b: 'b',
};

// No error;
const a: Array<someEnum> = ['a', 'b'];

// Is There someThing like;

// const typedArray: [K in someEnum]

It would be really cool to have such a feature; Is there some functionality to achieve the same. Thanks in advance.

Upvotes: 2

Views: 57

Answers (2)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250366

It's tempting to use some workaround to get tuple to union, please don't use it.

You can work around this issue in several ways, the simplest way is if the enum is under your control, start from the array instead of the enum:

const allPosibilitieForSomeEnum = ['a',  'b' , 'c'] as const
type someEnum = typeof allPosibilitieForSomeEnum[number];

You could use an object instead and use keys to get the keys.

Or you could use a function that validates that all memebers are present:

type someEnum = 'a' | 'b' | "c";

function checkEnum<TEnum>() {
    return function <TActual extends TEnum[]>(...p: TActual & ([TEnum] extends [TActual[number]] ? {} : {
        error: ["Array does not contain all members, expected: ", TEnum, "found:", TActual[number]]
    })) {
        return p
    }
}

const someObj =  checkEnum<someEnum>()("a", "b", "c") 
const someObj2 =  checkEnum<someEnum>()("a", "b") ///  Property 'error' is missing in type '["a", "b"]' but required in type '{ error: ["Array does not contain all members, expected: ", someEnum, "found:", "a" | "b"]; }'.

Upvotes: 1

pascalpuetz
pascalpuetz

Reputation: 5428

You want to create a tuple out of a union type. That is indeed possible but a little bit more complex. There is also an issue in the TypeScript Github repository that adresses this.

One of the answers there seems to work pretty well. Here the example in TypeScript Playground.

Upvotes: 0

Related Questions