Reputation: 36299
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
Reputation: 52213
Okay what if we forget the text transformation? If I provide
['foo', 'bar']
I want to getconstant.foo
andconstant.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
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
Reputation: 221372
There currently isn't a way to perform string transformation operations like toUpperCase
/ toLowerCase
in the TypeScript type system
Upvotes: 3