2017-12-03 1 views
1

Ich verwende joi und @types/joi mit TypeScript. Joi verfügt über eine extend-Methode, die es ermöglicht, joi zu erweitern, indem eine neue Instanz zurückgegeben wird, ohne dass die ursprüngliche joi-Bibliothek geändert wird. Ich habe damit eine erweiterte Instanz erstellt.Wie erweitert man ein Modul von Npm mit TypeScript?

Definition für diese erweiterte Instanz zu erstellen, habe ich versucht, Module Augmentation wie here unter Verwendung von Code:

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

jedoch, wie erwartet, das es durch Vermehrung ursprüngliche Definition ändert. Ich möchte Definitionen für die erweiterte Instanz erstellen, die alles vom Original erbt, ohne es zu modifizieren.

erweitert Auch Joi erstellt wie folgt:

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. Wie kann ich erweiterte Definitionen erstellen?
  2. Wie exportiert erweiterte Joi?

P.S. Ich lerne TypeScript und suchte nach einer Antwort für diese Frage, konnte aber keine Antwort finden, vielleicht, weil ich nicht an die Typoskript-Terminologie gewöhnt bin und nach falschen Begriffen suche.

Antwort

1

Joi.extend gibt eine neue Instanz des Moduls joi zurück, für das Sie den exportierten Typ Root verwenden können.

Sie müssen eine Schnittstelle erstellen, die Joi.Root erweitert, und eine andere, die den Basis-joi-Typ erweitert, den Sie erweitern. Sie können Ihre benutzerdefinierte joi Instanz wie jedes andere Objekt einfach exportieren.

Unten finden Sie ein Beispiel mit den round() und dividable() Regeln aus den API Documentation Beispielen auf extend().

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; 
Verwandte Themen