TypeScript-typ diskriminerade unioner i funktionsargument


Typen på det andra argumentet för funktionen beror på strängvärdet för det första argumentet. Jag skulle vilja få något som detta:

    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>> {
        ...
    }

För närvarande har jag: TS2394: Denna överlagringssignatur är inte kompatibel med dess implementationssignatur.

Svar #1

När du gör en överlagring måste implementationssignaturen vara kompatibel med alla överlagringar. Förresten kommer denna sista signatur inte att exponeras i .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()])
  }

Lekplats