Home > Net >  What does it mean having Typescript Interface and Class in same file?
What does it mean having Typescript Interface and Class in same file?

Time:03-18

I am reading through the @types/node repo, and finding stuff like this:

declare module 'https' {
  import * as tls from 'node:tls';
  import * as http from 'node:http';
  
  interface Server extends http.Server {}

  class Server extends tls.Server {
      constructor(requestListener?: http.RequestListener);
      constructor(options: ServerOptions, requestListener?: http.RequestListener);
      addListener(event: string, listener: (...args: any[]) => void): this;
      // ...
  }
}

Or this:

declare module 'url' {
  // ...
  interface Url {
      auth: string | null;
      hash: string | null;
      host: string | null;
      hostname: string | null;
      href: string;
      path: string | null;
      pathname: string | null;
      protocol: string | null;
      search: string | null;
      slashes: boolean | null;
      port: string | null;
      query: string | null | ParsedUrlQuery;
  }
  class URL {
    static createObjectURL(blob: Blob): string;
    static revokeObjectURL(objectUrl: string): void;
    constructor(input: string, base?: string | URL);
    hash: string;
    host: string;
    hostname: string;
    // ...
  }
  // ...
}

Or:

declare module 'fs' {
  export interface Stats extends StatsBase<number> {}
  export class Stats {}
}

What does it mean when you define both a class and an interface in the same file/namespace? When does URL refer to the class, when does it refer to the interface, etc.? Is this standard practice? What is the differences/similarities between the interface and class in this context, how do they relate?

CodePudding user response:

Classes and interfaces are subject to merging if they have the same name. You can consult the docs for what kind of merging is allowed. Class interface merging will result in an instance type for the class that has the members of the interface added to the instance type of the class.

interface PersonInterfaceBase {
    fromBaseInterface: number;
}
interface Person extends PersonInterfaceBase {
    fromInterface: string
}

class Person {
    fromClass: string  = ""
}

let p = new Person();
// All are valid
p.fromBaseInterface
p.fromClass
p.fromInterface

Playground Link

Using merging avoids having to redeclare the members of the interface in the class (but it also avoids their definition in the class and initialization checks on them).

In the case of Url and URL they are two different entities and have no relation.

  • Related