Typescript specialized overloads defined on a subclass or interface

后端 未结 3 936
南笙
南笙 2020-12-19 11:23

Is there a way to make the following work without having to define an implementation in the subclass which simply calls the superclass or unnecessarily repeats the non-speci

3条回答
  •  囚心锁ツ
    2020-12-19 12:10

    For a less verbose solution, check out ee-ts. It provides a typed EventEmitter class with support for:

    • strict event names (think string unions for the type in emit(type, ...args))

    • type-checked emit and on calls (never again emit the wrong type or expect the wrong types in a listener)

     

    import { EventEmitter as EE } from 'ee-ts'
    
    type User = { name: string }
    
    // All possible events must be explicitly defined as methods here.
    // The return type can be non-void because the `emit` method returns the last non-void value.
    // The return type can never be required, because `void` is implicitly added to every event.
    interface Events {
      login(user: User): void
      logout(): string
    }
    
    // Make your subclass generic to let users add their own events.
    class App extends EE {
      /* ... */
    }
    
    let app = new App()
    
    // The type of `user` is inferred.
    app.on('login', user => {
      console.log(user.name) // user.name is string
    })
    
    // Invalid argument types are caught.
    app.one('login', (invalid: boolean) => {}) // [ts] Type 'User' is not assignable to type 'boolean'.
    
    // Invalid return values are caught.
    app.one('logout', () => true) // [ts] Type 'boolean' is not assignable to type 'string | void'.
    
    // Unknown event names are caught.
    app.emit('invalid') // [ts] Argument of type '"invalid"' is not assignable to parameter of type '"login" | "logout"'.
    

提交回复
热议问题