Skip to content

Opaque subtypes of string cannot be used as object keys #6569

@wchargin

Description

@wchargin

If T is a transparent subtype of string, then an instance of T can
naturally be used as a key in an object. But the same does not hold if
T is an opaque subtype of string
:

// @flow
declare opaque type SpecialString: string;
declare var specialString: SpecialString;

// Even though `specialString` is a `string`, we can't use it as a key:
const bad1 = {[specialString]: 1};
const bad2: {[SpecialString]: number} = {[specialString]: 2};

// If we explicitly up-cast it to `string`, the expression typechecks
// (surprisingly), and things look okay...
const looksOkay3: {[SpecialString]: number} = {[(specialString: string)]: 3};
// ...but we suffer from https://github.com/facebook/flow/issues/6568:
const bad4: {[SpecialString]: number} = {[(specialString: string)]: "I am not a number"};

// If we do somehow get a useful reference to a value of such a type,
// then we can interact with it without problem...
declare var magic5: {[SpecialString]: number};
magic5[specialString] = 5;
// ...except for the (unrelated?) problem that `Object.keys` is useless.
const keys: $ReadOnlyArray<SpecialString> = Object.keys(magic5);

// To prove beyond any doubt---`specialString` really is a `string`:
const phew: string = specialString;

As noted in the above code, #6568 makes a potential workaround untenable.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions