When I try to compile this Typescript code
interface Foo {
[foo: "hello" | "world"]: string;
}
I get this error message
An index signature parameter type cannot be a union type. Consider using a mapped object type instead.
What is a mapped object type, and how do I use it?
A mapping object maps values of one type (the key type) to arbitrary objects. Mappings are mutable objects. There is currently only one mapping type, the dictionary . A dictionary's keys are almost arbitrary values.
A mapped object type operates on a set of singleton types and produces a new object type where each of those singletons is turned into a property name.
For example, this:
type Foo = {
[K in "hello" | "world"]: string
};
would be equivalent to
type Foo = {
"hello": string;
"world": string;
};
Keep in mind that a mapped object type is a distinct type operator - that syntax in the braces can't be used in interfaces, or object types with other members. For example
interface Foo {
[K in "hello" | "world"]: string; // ❌
}
produces the following error:
A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type.
Mapped object types are useful for a lot of different things. Read more here: https://www.typescriptlang.org/docs/handbook/2/mapped-types.html
This is invalid:
type DirectiveType = 'package-as' | 'externals' | 'move-folders' | 'ignore';
type Directives = { [key:DirectiveType]?: RootDirectives };
export class PkgmetaFile {
private _directives: Directives = {};
}
But this is valid:
type DirectiveType = 'package-as' | 'externals' | 'move-folders' | 'ignore';
type Directives = { [Key in DirectiveType as string]?: RootDirectives };
export class PkgmetaFile {
private _directives: Directives = {};
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With