vue.js - Vue 3 + Typescript emit-funktion "Ingen överlagring matchar detta anrop" även om funktionsnamnet är definierat. Det verkar som om ordningen spelar roll


Jag hittade ett konstigt felmeddelande i Vue 3 emit-funktionen när jag använder den med TypeScript. Exempel på kod för att återskapa:

export default defineComponent({
  emits: {
    emit1: (payload: number) => payload,
    emit2: (payload: string) => payload
  },
  methods: {
   ...
  }
}

när jag försöker kalla på emit1 på följande sätt, kompileras det utan fel: this.$emit("emit1", 1);

men om jag gör följande uppstår ett konstigt fel: this.$emit("emit1", "test");

TS2769: No overload matches this call.
  The last overload gave the following error.
    Argument of type '"emit1"' is not assignable to parameter of type '"emit2"'.

om jag ändrar ordningen på emit-funktionerna så här:

export default defineComponent({
  emits: {
    emit2: (payload: string) => payload,
    emit1: (payload: number) => payload
  },
  methods: {
   ...
  }
}

Självklart dyker också ett fel upp, men det här ger åtminstone mer mening:

TS2769: No overload matches this call.
  The last overload gave the following error.
    Argument of type 'boolean' is not assignable to parameter of type 'number'.

eftersom funktionsnamnet är definierat i båda fallen, är felmeddelande #1 meningslöst men #2 är det.

Mina frågor:

  • varför påverkar ordningen på funktionerna felmeddelandet?
  • bör/kan detta åtgärdas i Vue så att felet är begripligt i båda fallen? Kanske är detta också ett problem med TypeScript självt?

Svar #1

När du använder den senaste versionen av Vue CLI, här är det fullständiga felet som uppstår med vilken emit-ordning som helst. När du byter ordning på utskickarna visas båda felmeddelandena fortfarande, bara i omvänd ordning:

TS2769: No overload matches this call.
  Overload 1 of 2, '(event: "emit1", payload: number): void', gave the following error.
    Argument of type '"test"' is not assignable to parameter of type 'number'.

  Overload 2 of 2, '(event: "emit2", payload: string): void', gave the following error.
    Argument of type '"emit1"' is not assignable to parameter of type '"emit2"'. 

Detta gör det ganska klart vad som händer, även om det var mycket förvirrande eftersom du bara kunde se ett av meddelandena:

  • Vue testar emit mot alla potentiellt matchande emits-poster (dvs. överlagringarna). Både emit-namnet du använder i metoden och emit-värdet ges som parametrar till testfunktionen. Det är där du ser event, payload skickas som argument.

  • Med en överlagring har event-parametern en match men value-parametern orsakar ett typfel. Med den andra finns ingen event-match.

Relaterade artiklar