Skip to content

Type discrimination broken on generic, mapped type values when strictNullChecks:false #41530

Open
@ChuckJonas

Description

@ChuckJonas

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions