I am typing to build an input component which is basically a select
for enums in my app, and then define them for the concrete types in a series of one-liners. But whatever I try I seem to hit typing issues. The closest I've got is this:
import React from 'react';
type Props<T> = {
enumType: T;
value?: keyof T;
};
type IEnumInput<T = {}> = React.FC<Props<T>>;
const EnumInput: IEnumInput = ({ enumType, value }) => {
const options = Object.values(enumType).map((x: any) => x.toString());
return (
<div>
Will select from {options.join(',')}, current value is {value}
</div>
);
};
type CProps<T> = {
value?: keyof T;
};
enum MyEnum {
A = 'a',
B = 'b',
C = 'c',
}
const MyEnumInput = (props: React.PropsWithChildren<CProps<MyEnum>>) =>
EnumInput({ ...props, enumType: MyEnum });
The error I get is
Type '{ enumType: typeof MyEnum; value?: number | "big" | "link" | "small" | "sub" | "sup" | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | ... 35 more ... | undefined; children?: React.ReactNode; }' is not assignable to type 'Props<{}>'. Types of property 'value' are incompatible.
Type 'number | "big" | "link" | "small" | "sub" | "sup" | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | ... 32 more ... | undefined' is not assignable to type 'undefined'.
Type 'number' is not assignable to type 'undefined'.
Is this the right approach, and if so, what am I getting wrong?
TLDR;
Use typeof MyEnum
in place of MyEnum
.
Long answer:
You confuse enum as a value with enum as a type.
When you access MyEnum.A
you use it as a value, which in transpiled js is a plain object, then access its property '.A'.
When you refer to MyEnum
as a type, you're actually referring to the value part of that key-value struct, which in your case is string literal 'a' | 'b' | 'c'
'a' | 'b' | 'c'
'a' | 'b' | 'c'
.
If you want to get the type of the plain object MyEnum
, you need to use typeof MyEnum
.
As a side note, the same thing happens to class in TS.
When declare class Dog {}
, Dog
is both a type and a value.
When referring to Dog
as a type, it's the type of instance of this class. When referring to Dog
as a value, it's the Dog
class itself, aka, the constructor function, not the instance.
Now if you want to get the type of Dog
constructor function, you need to use typeof Dog
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.