New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Symbols as literal types #7436

Closed
Ciantic opened this Issue Mar 8, 2016 · 3 comments

Comments

Projects
None yet
5 participants
@Ciantic

Ciantic commented Mar 8, 2016

Consider following use case for string literals at the moment in Flux:

interface IAction {
    actionType: string
}
interface ISayHelloAction extends IAction {
    actionType: "SAY_HELLO";
}

// Somewhere in your code you check that the message is ISayHelloAction from that actionType string using normal if

function processActions(action: IAction|ISayHelloAction|...) {
    if (action.actionType === "SAY_HELLO") {
        // action is ISayHelloAction
    }
}

(Above example assumes #6028 gets fixed, for the moment one can implement own type guard.)

But it would be even better if one could use Symbol for the same thing:

interface IAction {
    actionType: Symbol
}
const SAY_HELLO: Symbol = Symbol();

interface ISayHelloAction extends IAction {
    actionType: SAY_HELLO; // "Symbol literal type"
}

function processActions(action: IAction|ISayHelloAction|...) {
    if (action.actionType === SAY_HELLO) {
        // ... is ISayHelloAction
    }
}

These symbol literal types has same type guard requirement as literal types.

@yortus

This comment has been minimized.

Contributor

yortus commented Mar 9, 2016

FYI there is some previous discussion about symbols as literal types starting here.

@Artazor

This comment has been minimized.

Contributor

Artazor commented Mar 14, 2016

Would be useful.

@mnpenner

This comment has been minimized.

mnpenner commented Jun 19, 2017

Here's another example where this would be useful:

export const __skip__ = Symbol('skip');

function filterMapArray<ValueType,ReturnType>(iterable: Iterable<ValueType>, callback: (v: ValueType, k: number) => ReturnType|symbol): ReturnType[] {
    let accum = [];

    let i = 0;
    for(let x of iterable) {
        let y = callback(x, i++);
        if(y !== __skip__) {
            accum.push(y);
        }
    }

    return accum; // TS2322: Type '(symbol | ReturnType)[]' is not assignable to type 'ReturnType[]'.
  Type 'symbol | ReturnType' is not assignable to type 'ReturnType'. Type 'symbol' is not assignable to type 'ReturnType'.
}

This code won't compile because I can only typehint against symbol, but not __skip__. TS can't determine that accum contains only ReturnTypes.

@Microsoft Microsoft locked and limited conversation to collaborators Jun 19, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.