6

Is it possible in TypeScript to assert that a const object literal is made in such a way where each key equals its value?

In other words:

// Good
const testIds: KeyEqualsValue = {
  foo: 'foo'
} as const

// Bad
const testIds: KeyEqualsValue = {
  foo: 'bar' // Error
} as const

2 Answers 2

7

Not with a single type, you can do it with a function:

function propAsValue<T extends { [P in keyof T]: P }>(o: T) {
    return o;
}
const testIds = propAsValue({
    foo: 'foo'
});

const testIds2 = propAsValue({
    foo: 'bar'
});

Playground Link

Or with an inline function, if you want to be terse and confuse everyone:

const testIds = (<T extends { [P in keyof T]: P }>(o: T) => o)({
    foo: 'foo'
});

Although I am not sure what your use case for this is, you might be better off with using Object.keys.

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

3 Comments

Very cool. This worked for me. Thanks! I use these test IDs for different elements on the page so I want them to be unique, and I also want to be able to type other functions parameters as being keyof typeof testIds. Your solution meets these requirements :)
T extends [...] keyof T My mind cannot wrap around how this is not a cyclical derivation.
Does this function ever get run during runtime? Or is it even compiled into the build?
0

Yes you can get the object keys with Object.keys then you can loop through the keys and compare the string values. If they do not equal you can throw an error.

1 Comment

Thank you but I wanted a compile-time check, not run-time.

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.