typescript symbol in object

Viewed 79

This is my ts code.

const actions = {
    APPROVE: Symbol('APPROVE'),
    SCHEDULE: Symbol('SCHEDULE'),
}

const obj = {
    [actions.APPROVE]: ({ amount }: {amount: number}) => {
        return `test`
    },
    [actions.SCHEDULE]: () => {
        return `test`
    },
}

console.log(obj[actions.SCHEDULE as any]())

The above code produces the following error: Expected 1 arguments, but got 0.

I don't know why it tries to get APPROVE instead of SCHEDULE.

Any idea ?

UPDATE: Just got rid of Symbol, but the problem is exactly the same.

here is the updated code:

const actions = {
    APPROVE: 'APPROVE',
    SCHEDULE: 'SCHEDULE'
}

const obj = {
    [actions.SCHEDULE]: () => {
        return `Schedules a new Proposal`
    },
    [actions.APPROVE]: ({ amount }: {amount: number}) => {
        return `Approves ${amount} ANT`
    }
}

console.log(obj[actions.SCHEDULE]())
2 Answers

TypeScript simply does not support using Symbols as object keys like that. There's an issue about this with more details about why and possibly when this might be supported.

The only reason your code compiles is that you used as any, but the moment you do that TypeScript can no longer discriminate between each value of the object based on the key, so it returns a union type which is valid for both, which is the one with one parameter.

Use strings for object keys instead and it'll work.

BTW, this is not a runtime error, but a TypeScript compiler error.

Make the amount optional, so that both functions have the same type and call the SCHEDULE with ({}):

const obj = {
    [actions.SCHEDULE]: () => {
        return `Schedules a new Proposal`
    },
    [actions.APPROVE]: ({ amount }: {amount?: number}) => {
        return `Approves ${amount} ANT`
    }
}

console.log(obj[actions.SCHEDULE]({}))

..or even easier:

const obj = {
    [actions.SCHEDULE]: () => {
        return `Schedules a new Proposal`
    },
    [actions.APPROVE]: (amount?: number) => {
        return `Approves ${amount} ANT`
    }
}

console.log(obj[actions.SCHEDULE]())
console.log(obj[actions.APPROVE](6))
Related