简体   繁体   中英

TypeScript type discriminated unions in function arguments

The type of the second argument of the function depends on the string value of the first argument. I'd like to get something like this:

    async action (name: 'create', args: { table: string, object: StorageObject }): Promise<StorageObject>;
    async action (name: 'createOrUpdate', args: { table: string, query: StorageQuery, object: StorageObject }): Promise<Array<StorageObject>>;
    async action (name: 'read', args: { table: string, query: StorageQuery }): Promise<Array<StorageObject>>;
    async action (name: 'update', args: { table: string, query: StorageQuery, object: StorageObject }): Promise<Array<StorageObject>>;
    async action (name: 'delete', args: { table: string, query: StorageQuery }): Promise<Array<StorageObject>> {
        ...
    }

Currently, I've got: TS2394: This overload signature is not compatible with its implementation signature.

When you are doing an overloading, the implementation signature need to be compatible with every of the overloads. Btw this last signature won't be exposed in the .d.ts

  async action(name: 'create', args: { table: string, object: StorageObject }): Promise<StorageObject>;
  async action(name: 'createOrUpdate', args: { table: string, query: StorageQuery, object: StorageObject }): Promise<Array<StorageObject>>;
  async action(name: 'read', args: { table: string, query: StorageQuery }): Promise<Array<StorageObject>>;
  async action(name: 'update', args: { table: string, query: StorageQuery, object: StorageObject }): Promise<Array<StorageObject>>;
  async action(name: 'delete', args: { table: string, query: StorageQuery }): Promise<Array<StorageObject>>;

  // The actual implementation that needs to cover every case above 
  async action(name: 'create' | 'delete' | 'update' | 'read' | 'createOrUpdate', args: { table: string, query: StorageQuery, object: StorageObject }): Promise<Array<StorageObject> | StorageObject> {
    if (name === 'create' || name === 'delete') {
      return Promise.resolve(new StorageObject())
    }

    return Promise.resolve([new StorageObject()])
  }

Playground

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