I have an NPM module that i've created, with some Typescript typings... and now I am trying to use this module in another application, and I am getting some issues! This could get confusing, so I will try to simplify the examples by omitting properties that aren't relevant to the question...

In the module I have the following in my index.d.ts file:

import * as Joi from 'joi'; import { RequestHandler } from 'express'; export interface ISteadyOptions { customTypes?: IParamType[], middleware?: (RequestHandler|ErrorRequestHandler)[], } export interface IParamType { name: string validator: (param: object) => Joi.ArraySchema }

Meanwhile, in my application I have something like this:

const opts: ISteadyOptions = { middleware: [ logger('dev'), express.static('images') ], customTypes: [ { name: "point", validator: function(param) { return Joi.array().items( config.getAvailableGroups() ) } } ] };

The idea being that I can only add Express request handlers into the middleware array, and I can define a customType (e.g. point ) with a Joi schema alongside it to be ran when required.

Problem 1 - I can put anything inside opts.middleware

For example, TypeScript says this is totally valid:

middleware: [ logger('dev'), express.static('images'), "not a request handler" ]

If I add something else invalid elsewhere in the opts object, then when VSCode gives me the error, I can see that for some reason the type for middleware has been changed to any[] .

I can't figure out why this would have happened?

Problem 2 - I can't get my validator function to work

I get this error:

Types of property 'customTypes' are incompatible. Type '({ name: string; description: string; validator: (param: object) => ArraySchema; example: string[...' is not assignable to type 'IParamType[]'. Type '{ name: string; description: string; validator: (param: object) => ArraySchema; example: string[]...' is not assignable to type 'IParamType'. Type '{ name: string; description: string; validator: (param: object) => ArraySchema; example: string[]...' is not assignable to type 'IParamType'. Types of property 'validator' are incompatible. Type '(param: object) => ArraySchema' is not assignable to type '(param: object) => ArraySchema'. Two different types with this name exist, but they are unrelated. Type 'ArraySchema' is not assignable to type 'ArraySchema'. Two different types with this name exist, but they are unrelated. Types of property 'validate' are incompatible. Type '{ <T>(value: T): ValidationResult<T>; <T>(value: T, options: ValidationOptions): ValidationResult...' is not assignable to type '{ <T>(value: T): ValidationResult<T>; <T>(value: T, options: ValidationOptions): ValidationResult...'. Two different types with this name exist, but they are unrelated. Type 'ValidationResult<any>' is not assignable to type 'ValidationResult<any>'. Two different types with this name exist, but they are unrelated. Types of property 'error' are incompatible. Type 'ValidationError' is not assignable to type 'ValidationError'. Two different types with this name exist, but they are unrelated. Types of property 'details' are incompatible. Type 'ValidationErrorItem[]' is not assignable to type 'ValidationErrorItem[]'. Two different types with this name exist, but they are unrelated. Type 'ValidationErrorItem' is not assignable to type 'ValidationErrorItem'. Two different types with this name exist, but they are unrelated. Types of property 'path' are incompatible. Type 'string[]' is not assignable to type string.

I was able to replicate my use case (shown below), and it worked as expected... I'm obviously doing something wrong... but I have no idea what?!