I created the SelectProps interface!
export interface SelectProps {
value: string
options: string[]
onChange: (value: any) => void
}
I created react component!
<Select
value="red"
options={['dark', 'white']}
onChange={(value) => console.log(value)}
/>
How do I make value one of the values of options ('dark' | 'white') ? That is, I want to get this type:
type Value = 'dark' | 'white'
I must say right away this solution is not suitable:
const options = ['dark', 'white'] as const
type Value = typeof options[number]
CodePudding user response:
Here is how to do it:
export interface SelectProps<O extends string> {
value: O & {}
options: O[]
onChange: (value: O) => void
}
const Select = <O extends string>(props: SelectProps<O>) => <div></div>
As the others have said, SelectProps
needs to be generic. We use O
as an array for options
and as the type for value
. Important here are two things:
First, the intersection with an empty object {}
for the value
field. This signals to TypeScript that the value
field shall not be used for inference of O
.
Secondly, we constrain O
to be a string
. This lets TypeScript infer the string literal types 'dark' | 'white'
instead of just string
.
function main() {
return (
<div>
<Select
value="red" // Error: Type '"red"' is not assignable to type '"dark" | "white"'
options={['dark', 'white']}
onChange={(value) => console.log(value)}
/>
<Select
value="dark"
options={['dark', 'white']}
onChange={(value) => console.log(value)}
/>
</div>
)
}
CodePudding user response:
You need to use typescript Generics:
export interface SelectProps<Value> {
value: Value
options: Value[]
onChange: (value: Value) => void
}
But you also need to change Select
component, so it also takes a type parameter
, and passes it to SelectProps
interface:
function Select<Value>(props:SelectProps<Value>){
...
}
CodePudding user response:
Add your type in the interface
export interface SelectProps {
value: Value
options: Value[]
onChange: (value: Value) => void
}