如何使用 TypeScript 从 npm 扩展模块?
How to extend a module from npm using TypeScript?
我正在使用 joi and @types/joi with TypeScript. Joi has an 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'
- 如何创建扩展定义?
- 如何导出扩展
Joi
?
P.S。我正在学习 TypeScript 并搜索了这个问题的答案,但找不到答案,可能是因为我不习惯 TypeScript 术语并搜索了错误的术语。
Joi.extend
returns 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;
我正在使用 joi and @types/joi with TypeScript. Joi has an 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'
- 如何创建扩展定义?
- 如何导出扩展
Joi
?
P.S。我正在学习 TypeScript 并搜索了这个问题的答案,但找不到答案,可能是因为我不习惯 TypeScript 术语并搜索了错误的术语。
Joi.extend
returns 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;