Skip to content

The typeof type operator should strip freshness from its operand #25469

Closed
@weswigham

Description

@weswigham

TypeScript Version: 3.0.0-dev.201xxxxx

Search Terms:

Code

interface Collection<T> {
  elems: T[];
}
interface CollectionStatic {
  new <T>(): Collection<T>;
}
declare const Collection: CollectionStatic;

const ALL = "all";
type All = typeof ALL;

const result: Collection<All> = new Collection();

Expected behavior:
No errors.

Actual behavior:

Type 'Collection<string>' is not assignable to type 'Collection<"all">'.
  Type 'string' is not assignable to type '"all"'.

typeof ALL copies the type of the ALL const - in this case, that is a widening literal "all", which is then, during return type inference for Collection, widened, causing the assignment of the resulting inference to fail. Intuitively, widening types aren't exposed syntactically and aren't simple to understand, and typically they only result from expression positions. typeof currently breaks that and copies a widening type into a type position where it behaves unexpectedly. The fix, IMO, is simple: typoef should strip freshness.

This issue cropped up due to a lib change (we removed a bogus no-arguments-result-in-any overload on Map and replace it with generic defaults) that exposed the error in an RWC test.

Metadata

Metadata

Assignees

No one assigned

    Labels

    In DiscussionNot yet reached consensusSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions