Skip to content

Unrelated overload signature affects inference #25917

Closed
@cartant

Description

@cartant

In fixing a problem with the typings for the RxJS first and last operators, I've stumbled across some weird behaviour with overload signatures.

TypeScript Version: next (3.1.0-dev.20180725)

Search Terms:

overload signature inference unrelated incorrect

Code

interface Foo<T> {}
interface Bar<T, S> {}

export function foo<T, S extends T>(predicate: (value: T) => value is S, defaultValue?: S): Bar<T, S>;
export function foo<T>(predicate: (value: T) => boolean, defaultValue?: T): Foo<T>;
export function foo<T>(predicate: (value: T) => boolean, defaultValue?: any): Bar<T, any> | Foo<T> {
  throw new Error('Unimplemented');
}

For the behaviour to be effected, strictFunctionTypes must be true and strictNullChecks must be false:

{
  "compilerOptions": {
    "strictFunctionTypes": true,
    "strictNullChecks": false
  },
  "files": ["index.ts"]
}

Expected behavior:

When passing a function that is not a user-defined type guard, I'd expect the inferred type to be independent of whether or not the type-guard-accepting overload signature is available or is commented out.

Actual behavior:

However, if the signature that accepts a type guard is available, the inferred type - for a call that does not involve a user-defined type guard - will be:

const predicated = foo(x => x === 's', 's'); // Foo<"s">

And if the signature that accepts a type guard is commented out, the inferred type - for a call that does not involve a user-defined type guard - will be:

const predicated = foo(x => x === 's', 's'); // Foo<string>

In RxJS, this causes a problem when the operators are used with pipe. If a return type with a string literal is inferred - e.g. MonoTypeOperatorFunction<"s"> - an error will be effected if the operators are used with a string source, as string won't be assignable to "s".

Also, why is the behaviour dependent upon the above-mentioned compiler options? In particular, why does it depend upon the strictNullChecks option?

Related Issues: None found.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions