I have problem with defined types and checking if a value is contained in that type.
Here is my example:
these are the types:
export type Key
If you check that the strings are the exact strings of the type, or if you check that they are not the strings that are not in the Key
type it will work:
export type Key = 'features' | 'special';
export type TabTypes = 'info' | 'features' | 'special' | 'stars';
function activeTabChanged(event: TabTypes) {
var activeTab: TabTypes = event;
if(event != 'info' && event != 'stars') {
let key: Key = event;
}
// OR
if(event == 'features' || event == 'special') {
let key: Key = event;
}
}
Edit
The problem with the type
definition is that it is erased at compile time, so at runtime there is no way to perform the check. A more verbose way of declaring the enum base on this page and a type guard can help acieve the effect:
/** Utility function to create a K:V from a list of strings */
function strEnum<T extends string>(o: Array<T>): {[K in T]: K} {
return o.reduce((res, key) => {
res[key] = key;
return res;
}, Object.create(null));
}
const Key = strEnum([
'features',
'special',
])
type Key = keyof typeof Key;
function isKey(key: string) : key is Key {
return Key[key] !== undefined;
}
export type TabTypes = 'info' | 'features' | 'special' | 'stars';
function activeTabChanged(event: TabTypes) {
var activeTab: TabTypes = event;
if(isKey(event)) {
let key: Key = event;
}
}
This example is worth it if the enums are large, otherwise the first version might work just as well.
This answer to a similar question might be useful. it doesn't exactly answer your question, but it shows a similar way to achieve the desired result.
In short, you can use array for inclusion checks, and type for type safety:
const keys = <const> ['features','special'];
export type Key = typeof keys[number];
const tabTypes = <const> ['info' ,'features' ,'special', 'stars'];
export type TabTypes = typeof tabTypes[number];
activeTabChanged(event: TabTypes) {
this.activeTab: TabTypes = event;
// it won't let me set the key here because key has a different type
// but the send event can be contained in type Key
// how can I check if the send event from type TabTypes is contained in type Key
if (event in keys) {
this.key: Key = event as Key;
}
}
You could use a string enum.
export enum Keys = {
Features = 'features',
Special = 'special',
}
// Compare it
if (currentKey === Keys.Special) { console.log('Special key is set'); }
In order to check if your value is defined in the predefined Enum at all you can do:
if (currentKey in Keys) { console.log('valid key'); }
I had the same need and found an easier way to do that in another thread. In summary, what Patrick Roberts says in that link (updated with this question values) is:
Don't over-complicate it.
function isOfTypeTabs (keyInput: string): keyInput is TabTypes {
return ['info', 'features', 'special', 'stars'].includes(keyInput);
}
See What does the `is` keyword do in typescript? for more information on why we don't just use a
boolean
return type.
Credits and full source here: https://stackoverflow.com/a/57065680/6080254