Что означает наличие интерфейса Typescript и класса в одном файле?

Я читаю репозиторий @types/node и нахожу такие вещи:

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;
      // ...
  }
}

Или это:

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;
    // ...
  }
  // ...
}

Или:

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

Что это значит, когда вы определяете и class, и interface в одном и том же файле/пространстве имен? Когда URL относится к классу, когда к интерфейсу и т. д.? Это стандартная практика? Каковы различия/сходства между интерфейсом и классом в этом контексте, как они соотносятся?

Примечание: Url и URL — разные идентификаторы. Ваш declare module 'url' пример не стыкуется с другими.

T.J. Crowder 17.03.2022 12:18

Оп, понял спасибо.

Lance 17.03.2022 12:22
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Мне нравится библиотека Mantine Component , но заставить ее работать без проблем с Remix бывает непросто.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
TypeScript против JavaScript
TypeScript против JavaScript
TypeScript vs JavaScript - в чем различия и какой из них выбрать?
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Не все нужно хранить на стороне сервера. Иногда все, что вам нужно, это постоянное хранилище на стороне клиента для хранения уникальных для клиента...
Что такое ленивая загрузка в Angular и как ее применять
Что такое ленивая загрузка в Angular и как ее применять
Ленивая загрузка - это техника, используемая в Angular для повышения производительности приложения путем загрузки модулей только тогда, когда они...
1
2
22
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Классы и интерфейсы подлежат слиянию, если они имеют одинаковое имя. Вы можете проконсультироваться с документы о том, какое слияние разрешено. Слияние интерфейса класса приведет к типу экземпляра для класса, в котором члены интерфейса добавлены к типу экземпляра класса.

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

Ссылка на игровую площадку

Использование слияния позволяет избежать повторного объявления членов интерфейса в классе (но также позволяет избежать их определения в классе и проверки их инициализации).

В случае Url и URL это две разные сущности и не имеют никакого отношения.

Есть идеи, что Зачем можно было бы написать отдельно? В частности, пример Node.js https кажется действительно странным.

T.J. Crowder 17.03.2022 12:23

@T.J.Crowder и http.Server, и `tls.Server` являются классами, поэтому вы не можете наследовать их оба. Если бы он сказал implements http.Server, ему пришлось бы повторно объявить всех членов http.Server в Server, так что это просто способ избежать этого.

Titian Cernicova-Dragomir 17.03.2022 12:27

Итак, в основном, форсируя немного множественного наследования (на уровне типа). :-)

T.J. Crowder 17.03.2022 12:29

Другие вопросы по теме