Let's say, I've:
type EventName = 'article:show' | 'article:hide';
const sendEvent = (eventName: EventName) => {
return eventName;
}
const eventMap = {
show: 'show',
hide: 'hide'
};
const sampleEventName = `article:${eventMap.show}`;
sendEvent(sampleEventName);
Now I'm getting an error:
Argument of type 'string' is not assignable to parameter of type 'EventName'.
So can't TS figure out it's going to be a match with EventName? I know I can always cast string
to EventName
, but what's the best way here?
CodePudding user response:
This transpiles successfully for me, using enums:
type EventName = 'article:show' | 'article:hide';
const sendEvent = (eventName: EventName) => {
return eventName;
}
enum eventMap {
show = 'show',
hide = 'hide'
};
sendEvent(`article:${eventMap.show}`);
CodePudding user response:
You have to be a bit more specific when you define your two constants, otherwise, the type that's inferred by TS is very wide.
type EventName = 'article:show' | 'article:hide';
const sendEvent = (eventName: EventName) => {
return eventName;
}
const eventMap = {
show: 'show',
hide: 'hide'
} as const; // <--- HERE
const sampleEventName = `article:${eventMap.show}` as const; // <--- HERE
sendEvent(sampleEventName); // <--- Now this works just fine
CodePudding user response:
You have to use the as const
assertion. This tells TS that the types in the object are not a generic string, but instead a specific string. The same happens with the dynamic string that you are building.
type EventName = 'article:show' | 'article:hide';
const sendEvent = (eventName: EventName) => {
return eventName;
}
const eventMap = {
show: 'show',
hide: 'hide'
} as const;
const sampleEventName = `article:${eventMap.show}` as const;
sendEvent(sampleEventName);
CodePudding user response:
You don't need to cast, some additional type declarations will do.
type EventMap = {
[key: string]: 'show' | 'hide'
}
const eventMap: EventMap = {
show: 'show',
hide: 'hide'
};
const sampleEventName: EventName = `article:${eventMap.show}`;
sendEvent(sampleEventName);