4

i want to create an error code counter, but having issues with typescript using enums and generics.

this is the working version (without generics)

enum ErrorCode  {
    MX1 = 'MX1',
    MX2 = 'MX2'
}

type Codes = keyof typeof ErrorCode;
type ErrorCodeCounter = {
    [code in Codes]: number
}

const counter = <ErrorCodeCounter>{}
counter[ErrorCode.MX1] = 3
counter['randomCode'] = 3 // Valid TS error: 'randomCode' does not exist on type 'ErrorCodeCounter

How can we make we make a generic Counter interface, to be used as:

const counter = <Counter<ErrorCode>>{}
counter[ErrorCode.MX1] = 3

one way that comes to mind is

type Counter<T> = {
    [code in keyof T] : number
}

but that does not work. Any ideas how to make a generic version?

Note that replacing enum by interface works but i would prefer Enums over interface

interface ErrorCodeI {
    MS1: string;
    MS2: string;
}

type Counter<T> = {
    [code in keyof T] : number
}
const counter = <Counter<ErrorCodeI>>{}
counter['MS1'] = 3
counter['random'] = 3 // Valid TS error.

1 Answer 1

6

You don't need keyof, the enum type itself is already the union of the enum elements you want to map over:

type Counter<T extends PropertyKey> = {
    [code in T] : number
}


enum ErrorCode  {
    MX1 = 'MX1',
    MX2 = 'MX2'
}

const counter = <Counter<ErrorCode>>{}
counter[ErrorCode.MX1] = 3
counter['randomCode'] = 3 //ERR

Playground Link

Sign up to request clarification or add additional context in comments.

1 Comment

this is great. didn't know about PropertyKey and couldnt' find it in docs. please share any resource with more context around this if you are aware. thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.