I have a TypeScript interface with two properties (type:string and args:object). The args may have different properties depending on the type. What type definition to I need to apply to args so the compiler/autocomplete will know which properties are allowed for args?
This is somewhat similar to how I use Actions in Redux, which do have a type and a payload and in my reducer the compiler knows by the switch-statement what the payload contains. But I can't get this to work with my object. I have read an excellent article here https://artsy.github.io/blog/2018/11/21/conditional-types-in-typescript/ but this describes the problem for a method with two args which depend on one another but not how to get this working for two properties within the same object.
export interface IObject { type: ObjectType parameters: ObjectParameters } export type ObjectType = "check" | "counter" export interface IParametersCheck { checked: boolean } export interface IParametersCounter { max: number min: number step: number } export type ObjectParameters = IParametersCheck | IParametersCounter If I have an IObject and set the type to "check" the compiler/autocomplete should offer the properties for IParametersCheck.
I think what you are actually looking for is a discriminated union. IObject should itself be a union:
export type IObject = { type: "checked" parameters: IParametersCheck } | { type: "counter" parameters: IParametersCounter } export type ObjectType = IObject['type'] //// in case you need this union export type ObjectParameters = IObject['parameters'] //// in case you need this union export interface IParametersCheck { checked: boolean } export interface IParametersCounter { max: number min: number step: number } You could also do it with conditional types but I think the union solution works better :
export interface IObject<T extends ObjectType> { type: T parameters: T extends 'checked' ? IParametersCheck: IParametersCounter } Or with a mapping interface:
export interface IObject<T extends ObjectType> { type: T parameters: ParameterMap[T] } type ParameterMap ={ 'checked': IParametersCheck 'counter': IParametersCounter } export type ObjectType = keyof ParameterMap
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With