55

In my TypeScript project, I use DefinitelyTyped definitions for external js dependencies.

Sometimes it might happen that these definitions are outdated. It might also happen than some libraries can add new methods at runtime, like express-validator in which you can define custom validator functions.

Therefore I would like to extend those .d.ts definitions adding new methods and/or properties.

So if I have my DefinitelyTyped defininiton in express-validator.d.ts:

declare module ExpressValidator {
  export interface Validator {
    is(): Validator;
    not(): Validator;
    isEmail(): Validator;
    ...
  }
}

how can I extend Validator interface within, for example, my application.ts ?

///<reference path='../typings/tsd.d.ts' />

import expressValidator = require('express-validator');
export var app = express();

app.use(expressValidator({
    customValidators: {
        isArray: function(value) {
            return Array.isArray(value);
        }
 }
}));

// How to extend Validator interface adding isArray() method??
Marco Ancona
  • 2,073
  • 3
  • 22
  • 37

2 Answers2

36

// How to extend Validator interface adding isArray() method??

You cannot do this in a file that is a module (some guidance here) and your file is a module because you have import expressValidator.

Instead create a extendedValidator.d.ts and add the new stuff for TypeScript's engine:

declare module ExpressValidator {
  export interface Validator {
     isArray: any;
  }
}
basarat
  • 261,912
  • 58
  • 460
  • 511
  • 1
    Do you have to do something specific with the `d.ts` file once it is created? I have done this but I still just get the error that my new property doesn't exist. Do I have to put it in a specific location or do something else to get it recognized by the compiler? – WillyC Nov 29 '16 at 17:49
  • @basarat do you have to "export" the interface? is that required? what happens when you don't export? – Mohamed Nuur Jan 17 '17 at 01:43
  • @MohamedNuur you have to export it if you want to make it publicly available. – Dzulqarnain Nasir Jan 30 '17 at 11:54
  • @NoNameProvided clarified it for me in this answer: http://stackoverflow.com/questions/41687894/typescript-d-ts-syntax-export-and-declare/41695486#41695486 -- hope you find it useful. – Mohamed Nuur Feb 09 '17 at 20:36
15

I was able to accomplish this by following the directions at https://www.credera.com/blog/technology-solutions/typescript-adding-custom-type-definitions-for-existing-libraries/. There they use the example of react.

import 'react';
 
declare module 'react' {
    interface OlHTMLAttributes<T> {
        type?: "1" | "a" | "A" | "i" | "I";
    }
}

I found this works really well for winston too.

cjbarth
  • 4,189
  • 6
  • 43
  • 62
  • 1
    Thank you so much. All i needed was importing the module at the top of the `.d.ts` file – refik Nov 11 '21 at 20:13