Wasn't sure how to word this.
type FooType = Record<string, number>;
type BarType = Record<string, string>;
type PossibleTypes = "Foo" | "Bar";
type TypeMap = {
Foo: FooType;
Bar: BarType;
}
type FProps<?> = {
type: PossibleTypes
data: TypeMap[?]
}
function F ({ type, data }: FProps<?>) {
return { type, data };
}
const {type, data} = F({ type: "Foo", data: { Foo: 42 } });
data.Foo = "Baz" //type error
I want to ensure the last line would throw a type error without having to explicitly type data. Is there a way to do this so that the value of the param type is used to defined the type of the data param?
I tried some generics, but I either was not doing it correctly or was going down the wrong path. In the above code I had tried FProps<PossibleTypes> then type FProps<T> and data: TypeMap[T] with error TS2536: Type 'T' cannot be used to index type.
CodePudding user response:
First, let's modify FProps so that it takes "Foo" | "Bar" as the generic type.
type FProps<T extends PossibleTypes> = {
type: T
data: TypeMap[T]
}
We also need to add a generic type to the function F which holds the type of the type property of the passed object.
function F<T extends PossibleTypes>({ type, data }: FProps<T>) {
return { type, data };
}
Now we get an appropriate error.
const { type, data } = F({ type: "Foo", data: { Foo: 42 } });
data.Foo = "Baz" // Error: Type 'string' is not assignable to type 'number'.
