Kousha
Kousha

Reputation: 36299

Typescript type from an array

Say I have:

const generate = (array: string[]) => {
   const obj: any = {};
   array.map(a => a.toUpperCase()].forEach(a => obj[a] = a);

   return obj;
}

So that I can do:

const constants = generate(['foo', 'bar']);
constants.FOO;
constants.BAR;

Is there anyway to define the type so that constants.BAZ for example errors out?

Upvotes: 1

Views: 90

Answers (3)

Aaron Beall
Aaron Beall

Reputation: 52213

Okay what if we forget the text transformation? If I provide ['foo', 'bar'] I want to get constant.foo and constant.bar

Yes, this can be achieved using type arguments and map types:

function generate<K extends string>(...keys: K[]): { [P in K]: string; } {
    const obj: any = {};
    keys.forEach(k => obj[k] = k);
    return obj;
}

const constants = generate("foo", "bar");
constants.foo; // string
constants.bar; // string
constants.baz; // Error

(I used a rest argument for no particular reason, you could make it a single array arg of the same K[] type.)

Upvotes: 0

JGoodgive
JGoodgive

Reputation: 1126

Ryans answer is great and if I may expand on it since you cannot make it a const but you can do this:

function generate<K extends string>(...keys: K[]): { [P in K]: P; } {
    const obj: any = {};
    keys.forEach(k => obj[k] = k;
    return obj;
}

const constants = generate("foo", "bar");
constants.foo;
constants.bar;
constants.baz; // fails because key is not in K
constants.foo = "fo"; // fails because value is not same as key.

Upvotes: 0

Ryan Cavanaugh
Ryan Cavanaugh

Reputation: 221372

There currently isn't a way to perform string transformation operations like toUpperCase / toLowerCase in the TypeScript type system

Upvotes: 3

Related Questions