【问题标题】:How to extend a module from npm using TypeScript?如何使用 TypeScript 从 npm 扩展模块?
【发布时间】:2018-05-17 00:40:00
【问题描述】:

我将 joi@types/joi 与 TypeScript 一起使用。 Joi 有一个extend 方法,它允许通过返回一个新实例来扩展 joi,而无需修改原始 joi 库。我用它创建了一个扩展实例。

要为这个扩展实例创建定义,我尝试了Module Augmentation,如here 所述,使用以下代码:

declare module 'joi' {
  // Add a new Schema type which has noChildren() method.
  interface CustomSchema extends ObjectSchema {
    noChildren(): this;
  }
}

但是,正如预期的那样,这会通过扩充原始定义来修改它。我想要的是为扩展实例创建定义,它继承原始的所有内容而不修改它。

还扩展Joi创建如下:

import * as Joi from 'joi';
const JoiExtended = Joi.extend({...some implementation...})
// How to export?
// export * from 'Joi' ---> In this case, original non-extended Joi is exported
// export default JoiExtended ---> Imported `Joi` reports: Cannot find namespace 'Joi'
  1. 如何创建扩展定义?
  2. 如何导出扩展Joi

附:我正在学习 TypeScript 并搜索了这个问题的答案,但可能找不到答案,因为我不习惯 typescript 术语并搜索错误的术语。

【问题讨论】:

    标签: node.js typescript joi


    【解决方案1】:

    Joi.extend 返回joi 模块的新实例,您可以使用导出的Root 类型。

    您需要创建一个扩展Joi.Root 的接口和另一个扩展您要扩展的基本joi 类型的接口。您可以像导出任何其他对象一样简单地导出自定义 joi 实例。

    下面是使用extend() 上的API Documentation 示例中的round()dividable() 规则的示例。

    import * as Joi from 'joi';
    
    interface ExtendedNumberSchema extends Joi.NumberSchema {
        round(): this;
        dividable(num: number): this;
    }
    
    interface ExtendedJoi extends Joi.Root {
        number(): ExtendedNumberSchema;
    }
    
    const customJoi: ExtendedJoi = Joi.extend((joi) => ({
        base: joi.number(),
        name: 'number',
        language: {
            round: 'needs to be a rounded number', // Used below as 'number.round'
            dividable: 'needs to be dividable by {{q}}'
        },
        pre(value, state, options) {
    
            if (options.convert && this._flags.round) {
                return Math.round(value); // Change the value
            }
    
            return value; // Keep the value as it was
        },
        rules: [
            {
                name: 'round',
                setup(params) {
    
                    this._flags.round = true; // Set a flag for later use
                },
                validate(params, value, state, options) {
    
                    if (value % 1 !== 0) {
                        // Generate an error, state and options need to be passed
                        return this.createError('number.round', {v: value}, state, options);
                    }
    
                    return value; // Everything is OK
                }
            },
            {
                name: 'dividable',
                params: {
                    q: joi.alternatives([joi.number().required(), joi.func().ref()])
                },
                validate(params, value, state, options) {
    
                    if (value % params.q !== 0) {
                        // Generate an error, state and options need to be passed, q is used in the language
                        return this.createError('number.dividable', {v: value, q: params.q}, state, options);
                    }
    
                    return value; // Everything is OK
                }
            }
        ]
    }));
    
    
    const schema = {
        a: customJoi.number().round().dividable(3)
    };
    
    const result = customJoi.validate({a: 4.1}, schema); // will fail because 4 is no divisible by 3
    
    console.log(result);
    
    export = customJoi;
    

    【讨论】:

    • 你们能帮我解决这个问题吗question
    猜你喜欢
    • 2016-11-08
    • 2018-03-08
    • 2018-06-13
    • 1970-01-01
    • 2016-07-18
    • 2020-06-13
    • 1970-01-01
    • 2013-10-05
    相关资源
    最近更新 更多