A third-party library exports a variable containing an enum instead of the enum itself:
enum Size { S, M, L }
export const sizeType: typeof Size = Size;
In my own code, how can I declare that something has type Size
?
import { sizeType } from '...';
interface Props {
size: /* What goes here that's equivalent to 'Size'? */
}
const props: Props = { size: sizeType.S };
props.size = sizeType.L;
Here are some declarations I tried that don't work:
size: typeof sizeType;
// error: Type 'Size' is not assignable to type 'typeof Size'.
size: typeof sizeType['S'];
// error: Type 'Size.L' is not assignable to type 'Size.S'.
size: InstanceType<typeof sizeType>;
// error: Type `typeof Size' does not satisfy the constraint 'abstract new (...args: any) => any`.
Since you don't have access to the enum, the only option will be to get the type of the values of the enum by using the sizeType
:
// typeof Size
type Case1 = typeof sizeType
// typeof Size
type Case2 = typeof Size
Now, by using the indexed access let's get the type of every value in union format:
// Size
type Case3 = typeof sizeType[keyof typeof sizeType]
// Size
type Case4 = typeof Size[keyof typeof Size]
With the enums, the whole thing looks a bit weird and that's why I personally prefer to use const assertion + the satisfies operator on javascript object:
const SIZE = {
S :0,
M: 1,
L: 2,
} as const satisfies Record<string, number>
Anyway, moving back to the problem, let's test the type that we got in the last cases:
const case3A: Case3 = Size.S
const case3B: Case3 = 'error' // error
const case4A: Case4 = Size.S
const case4B: Case4 = 'error' // error
Looks good!
Usage:
interface Props {
size: typeof sizeType[keyof typeof sizeType];
}
If you would like to shorten the code, you could use the ValueOf
utility type described in this answer:
type ValueOf<T> = T[keyof T];
interface Props {
size: ValueOf<typeof sizeType>;
}