3

Please have a look at the following TypeScript code. It's clear that the type inference behaves like described in the comments.

Now the question: Is it somehow possible to change the definition of type V2 = ... in a way, that it infers to type "someOtherValue" and not to string in general any longer?

As far as I understand TypeScript's type inference, this is absolutely NOT possible ... but who knows, maybe I am wrong. To be on the safe side I better ask the TypeScript community for help. Thanks.

const config1 = { value: 'someValue' as const } 

type K1 = keyof typeof config1      // type K1: "value" (not string in general)
type V1 = (typeof config1)['value'] // type V1: "someValue" (not string in general)

const config2 = { value: 'someOtherValue' } 

type K2 = keyof typeof config2      // type K2: "value" (not string in general)
type V2 = (typeof config2)['value'] // type V2: string

TypeScript Playground: Demo

2 Answers 2

2

you need to cast const on the whole config2 too.

const config2 = { value: 'someOtherValue' } as const;

otherwise it always will be string.


with the key access

const config1 = { value: 'someValue' as const } 

type K1 = keyof typeof config1      // type K1: "value" (not string in general)
type V1 = (typeof config1)['value'] // type V1: "someValue" (not string in general)

const config2 = { value: 'someOtherValue' } as const;

type K2 = keyof typeof config2 // type K2: "value" (not string in general)
type V2 = (typeof config2)[K2] // type V2: "someOtherValue"
Sign up to request clarification or add additional context in comments.

1 Comment

@ satanTime + @ JózefPodlecki: To write that as const not after the string itself but after the object literal is actually quite a nice idea. In my actual use case - which is a bit more complicated that that simple example ;-) - there is a function that gets a large configuration object as argument, and there I do not want to write as const a dozens time after some special strings... but if I just write as const one time after the large configuration object, type inference works as desired. Thank you very much guys, you were really a big help :-)
1

Now the question: Is it somehow possible to change the definition of type V2 = ... in a way, that it infers to type "someOtherValue" and not to string in general any longer?

Yes, you have to tell typescript that type is not going to change with const assertion. You can either apply it to the value prop or the whole object as @satanTime suggested.

Why? Because typescript assumes you might do following thing.

const config2 = { value: 'someOtherValue' } 
config2.value = "something different"

With const assertion applied type checker can decide to do type narrowing.

const config1 = { value: 'someValue' as const } 
config1.value = "test" // Type '"test"' is not assignable to type '"someValue"'.
const config2 = { value: 'someOtherValue' } as const
config2.value = "test" // Cannot assign to 'value' because it is a read-only property.

Comments

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.