I have a javascript object that looks like
I am trying to assign types of all the elements in the object to a variable where I am facing the issue,
whereas I am able to assign it when I mention the constants separately instead of using it them in an object in the second code snippet
const a = Object.freeze({ REMOVE_ITEM:'REMOVE_ITEM' ADD_ITEM:'ADD_ITEM' }); //How to assign the types of all elements in the above object const b = typeof ? // All Properties in the above object ((Facing Problem Here)); //I Can do it if const REMOVE_ITEM ='REMOVE_ITEM'; const ADD_ITEM = 'ADD_ITEM'; const b = typeof REMOVE_ITEM | typeof ADD_ITEM;
You can use TypeScripts as const
notation ( found here ).
const a = Object.freeze({
REMOVE_ITEM: 'REMOVE_ITEM',
ADD_ITEM: 'ADD_ITEM'
} as const);
// assign typeof
const b: typeof a = {} as any; // you can ignore `{} as any` - only here for example
b; // type is { REMOVE_ITEM: 'REMOVE_ITEM', ADD_ITEM: 'ADD_ITEM' }
b.REMOVE_ITEM; // = 'REMOVE_ITEM'
b.ADD_ITEM; // = 'ADD_ITEM'
// destructure
const { REMOVE_ITEM, ADD_ITEM } = a;
REMOVE_ITEM; // = 'REMOVE_ITEM'
ADD_ITEM; // = 'ADD_ITEM'
Here is a stackblitz so you can see the types in action.
As I understood you, you are trying to export
a type
to make use of it in another file. This is quite easy:
File with your type definition (myType.ts / myType.d.ts):
export type MyType = {
foo: boolean
bar: 'foo' | 'bar'
}
File where you want to use that type:
import { MyType } from './myType' // should be in the same folder, otherwise correct the path
const myVar: MyType = false // error
const myVar: MyType = { foo: false, bar: 'foo' } //working
You can not define any types during the runtime since types will be removed while transpiling. But you can define an enum
and use it to define your types:
enum MyEnum {
FOO_BAR = 'foo_bar',
LORD_OF = 'the_rings'
}
type MyOhterType = {
fooBar: MyEnum
}
const myOtherVar: MyOtherType = {
fooBar: MyEnum.FOO_BAR
}
Looks like you are mixing JavaScript's typeof
operator with TypeScript's - both do not accomplish the same thing.
In JS, typeof something
will evaluate to a simple runtime string (such as 'number'
, 'string'
, 'object'
...) which your app can then use for comparison purposes. This is not what you want here.
In TS, typeof
helps you extract the implied TS type out of a JS variable, as a meaningful structure - a true TypeScript type . This is helpful when you want to define complex TS types out of existing JS code.
const a = Object.freeze({
REMOVE_ITEM: 'REMOVE_ITEM',
ADD_ITEM: 'ADD_ITEM'
});
// ^ to TypeScript, this is similar to this type:
// Readonly<{ REMOVE_ITEM: string; ADD_ITEM: string; }>
To extract its implied type:
type AObject = typeof a;
// Readonly<{ REMOVE_ITEM: string; ADD_ITEM: string; }>
To have type definitions matching the keys in that object, use keyof
when defining your TS type matching any key:
type AKey = keyof AObject;
// "REMOVE_ITEM" | "ADD_ITEM"
// or in a strictly similar way:
type AKey = keyof typeof a;
// "REMOVE_ITEM" | "ADD_ITEM"
Now, back to runtime code. Once you have extracted the AKey
type matching the keys of a
, you can enforce type consistency for some JS values and arguments where needed:
function createActionObject(actionType: AKey) {
return { type: actionType };
}
const action1 = createActionObject('REMOVE_ITEM');
// compiles and works as expected
const action2 = createActionObject('SOME_BAD_KEYNAME');
// TypeScript Error ->
// Type '"SOME_BAD_KEYNAME"' is not assignable to type '"REMOVE_ITEM" | "ADD_ITEM"'
Finally , you cannot "assign" TS types to a JS variable, you can merely describe what a JS variable needs to look like so TypeScript validates it before eventually transpiling to JS. If you tried to get an array that lists all keys in a
, you need to use traditional JS methods:
const b = Object.keys(a);
// to JavaScript: will be ['REMOVE_ITEM', 'ADD_ITEM']
// to TypeScript: string[]
// or, to get stronger typings for `b` rather than just `string[]`:
const b = Object.keys(a) as (keyof typeof a)[];
// to JavaScript: will be ['REMOVE_ITEM', 'ADD_ITEM']
// to TypeScript: ('REMOVE_ITEM' | 'ADD_ITEM')[]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.