简体   繁体   中英

Typescript function arguments based on types with enums as keys

Lets say that I have an enum with a set of action types:

export enum ActionTypes {
  action1 = 'action1',
  action2 = 'action2',
  action3 = 'action3',
  // ...etc
}

And I have a set of payload types that a function wants when performing that action, which is keyed off the action types themselves:

export type ActionPayloads = {
  [ActionTypes.action1]: boolean,
  [ActionTypes.action2]: string,
  [ActionTypes.action3]: void,
  // ...etc
}

I want to use a function that takes as its first parameter the action type from the enum, and then use TS hinting to have it infer the payload type for argument two:

function exampleFn<T extends ActionTypes, U extends ActionPayloads[T]> (type: T, data?: U): void {
  //...
}

I feel like this would work, but even if I change ActionPayloads to an interface, in both cases for U extends ActionPayloads[T] I get the error TS2536: Type 'T' cannot be used to index type 'ActionPayloads'

Am I missing something here? I feel like this should work, given that there's nothing fancy going on with the usage of the enum.

Updated to reproduce the error

The error can be reproduced by omitting any possibility of ActionTypes from ActionPayloads .

export enum ActionTypes {
  action1 = "action1",
  action2 = "action2",
  action3 = "action3",
  // ...etc
}

export type ActionPayloads = {
  [ActionTypes.action1]: boolean;
  // [ActionTypes.action2]: string; // accidentally omit action2
  [ActionTypes.action3]: void;
  // ...etc
}

function exampleFn<T extends ActionTypes, U extends ActionPayloads[T]>(type: T, data?: U): void {

}

Since exampleFn takes all possibilities of ActionTypes as T , U expands ActionPayloads[T] with such. If any possibility of T is omitted in ActionPayloads , T cannot be used to index ActionPayloads . That's what the error message tells.

Okay I figured it out. My enum, which is quite a bit larger than the example, had one entry that was not accounted for in the payload type.

This entire thing was caused by a mismatch; it works fine.

Long story short, the error message does not really provide information of use, and make sure that your keys from both enum and type line up. Huge waste of time here.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM