Как дополнить методы сервера Hapi.js при использовании TypeScript? - PullRequest
0 голосов
/ 16 января 2019

Для добавления модуля hapi для добавления проверки типа для методов сервера, следующий код:

import { Server } from 'hapi';

declare module 'hapi' {

    export interface Server {
        methods: {
            getUsername: () => Promise<string>;
        };
    }
}

Однако это не работает, потому что пакет @types/hapi уже определяет methods как:

readonly methods: Util.Dictionary<ServerMethod>;

Из этого вопроса StackOverflow Насколько я знаю , невозможно переопределить существующее свойство. Но я не уверен. Я не мог найти документацию по этому поводу. Если это не так, как я могу дополнить / исправить / исправить информацию о типе?

В качестве обходного пути я создал новый интерфейс сервера Hapi.js, который расширяет оригинальный интерфейс. Таким образом, вместо использования интерфейса hapi Server, я использую тот, который создал:

// src/augment.d.ts
import { Server as HapiServer } from 'hapi';

export interface Server extends HapiServer {

    methods: {
        getUsername: () => Promise<string>;
    };
}

// In my file src/server.ts file
import { Server } from 'src/augment';

// NOW IT TYPECHECKS CORRECTLY
const username = server.methods.getUsername();

Это правильный подход?

1 Ответ

0 голосов
/ 16 января 2019

Хотя мы не можем изменить тип существующего поля в интерфейсе, мы можем изменить тип поля в этом случае. Тип поля Util.Dictionary<ServerMethod>. Хотя Util.Dictionary используется в нескольких местах, единственное место, где он используется с аргументом типа ServerMethod, предназначено для этого члена.

Мы можем расширить интерфейс Dictionary с помощью дополнительных методов, и методы будут отображаться только в том случае, если параметр типа равен ServerMethod (также мы делаем небольшой магический insipider из здесь , чтобы не отображать методы, если T это any)

declare module 'hapi' {
    export namespace Util {
        type IfAny<T, Y, N> = 0 extends (1 & T) ? Y : N; 
        export interface Dictionary<T> {
            getUsername<T extends ServerMethod>(this: Dictionary<T> & IfAny<T, never, {}>) : Promise<string>;
        }
    }
}

let d = new Server({})
let f!: Util.Dictionary<any>;

d.methods.getUsername() // type checked

Примечание В идеале был бы выделенный тип для methods, который позволил бы нам добавлять к нему методы, не расширяя очень общий интерфейс Dictionary, но типизация - это то, чем они являются сейчас. Кто-то может сделать запрос на создание нового интерфейса для methods ....

...