Description
Running into what I think is a bug with type discrimination of a function when you have a mapped type on a generic type . I've tried to make the reproduction as simple as possible.
TypeScript Version: 4.1.0-beta
Search Terms:
discrimination, generic, mapped type, strictNullChecks off
Code
type Mapping<T> = { [key in keyof T]?: string | (() => string) };
function foo<T>(mapping: Mapping<T>) {
const results: {[key: string]: string} = {};
for (const key in mapping) {
const valueTransform = mapping[key];
if (typeof valueTransform === 'function') {
results[key] = valueTransform(); //! This expression is not callable...
} else if(typeof valueTransform === 'string') {
results[key] = valueTransform;
}
}
return results;
}
Expected behavior:
Actual behavior:
strictNullChecks:false
I get the following error:
This expression is not callable.
Not all constituents of type 'string | (() => string)' are callable.
Type 'string' has no call signatures.
If you change it back to true
, it will work as expected. It seems to have something to do with the combination of generics & mapped types, as if you change to reference Foo
directly the code will compile.
type Mapping<T> = { [key in keyof Foo]?: string | (() => string) };
Also the discrimination only seems to break on the typeof valueTransform === 'function'
Playground Link: Playground Link
Related Issues:
#27470