I have an Object Type Options
with two keys:
strategy
: a function that requires one parameter of unknown type parameter
: same type as strategy
's first argument I want to be able to do the following
type FooParameter = { foo: string }
type BarParameter = { bar: string }
const fooOptions: Options = {
strategy: (parameter: FooParameter) => {},
parameter: { foo: 'foo' }
}
const barOptions: Options = {
strategy: (parameter: BarParameter) => {},
parameter: { bar: 'bar' }
}
The type fooOptions.parameter
should be inferred from fooOptions.strategy
and barOptions.parameter
from barOptions.strategy
Is that possible with TypeScript today?
The only way I can imagine to do this is using a generic type. I think it's unlikely there is a solution where the compiler will check that parameter
is a suitable argument for strategy
without using a generic type.
type Options<T> = {
strategy: (parameter: T) => void,
parameter: T
}
This means that if Options
is used in a type annotation then you have to provide a type parameter:
const fooOptions: Options<FooParameter> = {
strategy: (parameter: FooParameter) => {},
parameter: { foo: 'foo' }
}
function useOptions<T>(o: Options<T>): void {
o.strategy(o.parameter);
}
However, anywhere you allow the compiler to infer the type (ie whenever you don't use a type annotation), it is not necessary to provide an explicit type for the generic type parameter. In particular, users of an API such as the useOptions
function can pass an object literal, and enjoy the benefits of type-checking and type inference:
useOptions({
strategy: param => {
let x = param.x; // Inferred as number
let y = param.y; // Inferred as string
// Error: Property 'z' does not exist on type '{ x: number, y: string }'
let z = param.z;
},
parameter: { x: 1, y: 'foo' }
});
Note that the user in this example doesn't have to explicitly write { x: number, y: string }
or an equivalent type in order to use the API.
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.