Stack Overflow Asked by Joji on September 11, 2020
I am trying to type my action. Here is the code.
type Increment = {
type: 'INCREMENT'
payload: number
}
const action: Increment = {
type: 'INCREMENT',
payload: 1
}
console.log(action);
Then I wanted to extract 'INCREMENT'
into its own variable so I can use it in multiple places. So I did this
const INCREMENT = 'INCREMENT'
type Increment = {
type: INCREMENT
payload: number
}
const action: Increment = {
type: 'INCREMENT',
payload: 1
}
console.log(action);
However the TS compiler is yelling at me and says
‘INCREMENT’ refers to a value, but is being used as a type here. Did
you mean ‘typeof INCREMENT’?
so I had to add typeof
in front of INCREMENT
to make it happy, as in
type Increment = {
type: typeof INCREMENT
payload: number
}
I don’t understand why is that when I am using a variable to reference the string suddenly the breaks the rule. Also shouldn’t typeof INCREMENT
be a string string
. I thought it would be equivalent to type: string
but apparently here I cannot assign type
with anything string other than INCREMENT
. Can someone explain this to me?
In your first example, you were using a TypeScript feature called literal types which allow you to specify the exact value a string type variable can have. In this case the property type
can only have the string value INCREMENT
.
type Increment = {
type: 'INCREMENT'
payload: number
}
When you assigned that string literal to a variable using const
, TypeScript no longer recognizes it as a type but as an actual value. Hence the error message 'INCREMENT' refers to a value...
.
If you assign that literal to a type
variable that would work, as TypeScipt will see that as a type and not a value.
type INCREMENT = 'INCREMENT';
type Increment = {
type: INCREMENT
payload: number
};
However, you won't be able to "reuse" the actual string literal as a value it in multiple places.
One other solution I would recommend is using string enums. For example:
enum IncrementType {
INCREMENT = 'INCREMENT',
DECREMENT = 'DECREMENT' // Added this just as an example
}
type Increment = {
type: IncrementTypes
payload: number
}
const action: Increment = {
type: IncrementType.INCREMENT,
payload: 1
};
Answered by JoshA on September 11, 2020
It's because with const INCREMENT = 'INCREMENT'
you have a string
value but you're using it to declare a type. That's why typeof INCREMENT
works; that's a string literal so you get type: "INCREMENT"
which is like a sub-type of string
(it is-a string
). However, it can only have a single value of "INCREMENT". Like so:
const INCREMENT = 'INCREMENT'; // the apparent type is 'INCREMENT'
console.log(typeof INCREMENT); // the actual type is string
type Increment = {
type: typeof INCREMENT,
payload: number
}
const action: Increment = {
type: INCREMENT,
payload: 1
}
console.log(typeof action.type); // string
console.log(action.type); // INCREMENT
If you want use something like that in more than one place and will likely have more than one type
. You can try an enum
.
enum Type {
INCREMENT = "INCREMENT",
FOO = "FOO"
}
type Increment = {
type: Type
payload: number
}
const action: Increment = {
type: Type.INCREMENT,
payload: 1
}
console.log(action.type); // INCREMENT
Answered by ChiefTwoPencils on September 11, 2020
Try this: instead of const define new type
type INCREMENT = 'INCREMENT'
type Increment = {
type: INCREMENT
payload: number
}
const action: Increment = {
type: 'INCREMENT',
payload: 1
}
console.log(action);
Answered by Stanislav Berkov on September 11, 2020
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP