ISSUE: I found @types/lodash method first doesn't cover the case type of the input is union of two (multiple) typed arrays: // In my file I have import * as _ from 'lodash';
interface First {
name: string;
}
interface Second {
age: number;
}
function performSomeLogic(): First[] | Second[] {
if (Math.random() > 0.5) return [{name: 'Alice'}, {name: 'Bob'}];
return [{age: 42}, {age: 33}];
}
// we got some array First or Second of type. ok
const returnedData = performSomeLogic(); // we got some array First or Second of type. ok
// we expect value is First or Second of type. NOT ok.
// *******************
// TS ERROR
// TS2345: Argument of type 'First[] | Second[]' is not assignable to
// parameter of type 'ArrayLike<First>'.
// *******************
const firstValueOfData = _.first(returnedData);
// further steps could be ..
const proceedWithValueOfData = (value: First | Second) => Object.keys(value);
proceedWithValueOfData(firstValueOfData);
IDEA: I came up with the proper interface for _.first(). I try to put it into the typings.d.ts add refer it for bundler:
// typings.d.ts
type DeriveArrTypes<T> = T extends (infer R)[] ? R : T;
// So DeriveArrTypes<First[] | Second[]> returns First|Second union
declare module 'lodash' {
// LoDashStatic IS THE INTERFACE LODASH HAS HAD. FIRST IS DECLARED IN IT. I WANT TO ADD ITS EXTENDED DECLARATION
interface LoDashStatic {
first<T extends []>(value: T): DeriveArrTypes<T> | undefined;
}
}
SUCCESS - NO: But that doesn't work. Typescript stops displaying any errors (including others different). I use WebStorm as IDE it continue highlighting.
ENV: It is a frontend project that is served by Typescript for transpiling and Webpack for bundling (due to its long continuous liveness :)). From webpack.config.js:
// the rule for ts
{
test: /\.ts$/,
use: [{
loader: 'ts-loader',
options: {
// disable type checker - we will use it in fork plugin
transpileOnly: true
}
}],
},
// plugins section
plugins: [
// bla-bla plugins
...
new ForkTsCheckerWebpackPlugin({
tsconfig: __dirname + '/tsconfig.json'
})
]
From tsconfig.json:
"compilerOptions": {
// bla-bla options
...
"typeRoots": [
"node_modules/@types"
],
}
// I ADDED THIS
"include": [
"app/typings/**/*"
],
As I created app/typings directory and put typings.d.ts into it.