Hur tilldelar man korrekt typ till en klassmetod i TypeScript?


Under konstruktionen av detta inlägg löste jag mitt problem, men jag tycker fortfarande att det kan finnas ett annat tillvägagångssätt och jag skulle vilja veta det.

...

Jag har en klass där jag behöver ha två metoder med samma inmatning och ingen av dessa metoder har något returvärde. De har bara något olika kroppar.

Eftersom jag kan lägga till vissa ändringar i dessa metoder, skulle jag vilja ha dem nedskrivna på ett ställe (istället för att skriva varje enskild metod individuellt). Det skulle också se renare ut.

Nedan skapade jag förenklad exempelkod för att simulera mitt problem..

...

Jag har kollat dokumentation om typningsfunktioner, men jag har inte sett att dessa problem återges på metoder.

Metoderna "meow1" och "meow5" fungerar. Men jag förväntar mig fortfarande att det måste finnas ett annat tillvägagångssätt (utan användning av tilldelningsoperatorn).

Hur skriver man om "meow4" utan tilldelningsoperator?

Är det möjligt att lämna tomma parenteser, om typen beskriver funktionen korrekt? ("meow3" och "meow6")

type MeowMethodType = (meowText:string) => void;

Detta är vad jag hittade i dokumentationen:

const meow:MeowMethodType = (meowText:string) => {
    console.log(meowText)
}

Och detta är vad jag försökte:

class Cat {
    // Works, but does not solve my issue..
    meow1 (meowText:string):void {
        console.log(meowText);
    }

    // Error: A function whose declared type is neither 'void' nor 'any' must return a value.
    meow2 (meowText:string):MeowMethodType {
        console.log(meowText)
    }

    // Is such thing possible?
    meow3:MeowMethodType () {
        console.log(meowText)
    }

    // Produces many errors, so I am not sure, how to correct it.
    meow4:MeowMethodType (meowText:string) {
        console.log(meowText)
    }

    // This one works!
    meow5:MeowMethodType = (meowText:string) => {
        console.log(meowText)
    }

    // This one does not..
    meow6:MeowMethodType = () => {
        console.log(meowText)
    }
}

Tack för alla tips eller ledtrådar..

Svar #1

Det verkar som att du vill minska mallkod. Detta är endast möjligt när man definierar objekt och det innebär att flytta mallkoden någon annanstans:

type MeowMethodType = (meowText:string) => void;

interface Meow {
  meow1: MeowMethodType
  meow2: MeowMethodType
}

type Implement<Interface> = Interface & { [k: string]: unknown }

const Cat = {
  meow1(x) {
    //  ^? string
  },

  meow2(x) {
    //  ^? string
  },

  run(distance: number) {

  }
} satisfies Implement<Meow> ;

Att använda satisfies med Implement låter TS upptäcka andra metoder som run och samtidigt härleda typen för argumenten x som string.

Om du behöver en klass, kommer implementering av ett gränssnitt bara att tvinga dig att skriva metoderna enligt gränssnittet, vilket är okej: det förhindrar misstag när gränssnittet ändras, men det tar inte bort mallkod.

class Cat implements Meow {
  meow1(x: string) {
    //     ^^^^^^ you are forced to add this
  }

  meow2(x: string) {
    //     ^^^^^^ you are forced to add this
  }

  run(distance: number) {

  }
}

I meow5 försummade du också att du kunde ta bort typannoteringen på parametern

meow5:MeowMethodType = (meowText) => {
  //                       ^? string
}

lekplats