Reputation: 10371
I am writing a declaration file which should declare a global type and strict to a specific list of string phrases.
These string phrases are actually part of property keys in an object located in a JSON file.
Two questions:
Object.keys
and Array.map
?Let me give you a code example.
Let's say we have the following JSON file named data.json
:
{
"someList": {
"#key1": {"a": 1, "b": 2},
"#key2": "some value",
"#key3": 1234
}
}
Now, I want to create the following declaration file global.d.ts
:
import data from './data.json';
declare global {
type AllowedKeys = Object(data.someList).map(key => key.substr(1));
}
Basically, I need the type to be defined (dynamically as JSON file changes) like this:
type AllowedKeys = "key1" | "key2" | "key3";
Any help or at least guidance would be appreciated.
Upvotes: 3
Views: 2223
Reputation: 773
EDIT: You can now use template string literals to infer sub-string starting from given character, like so:
import data from "./data.json";
export type AllowedKeys = keyof typeof data["someList"] extends `#${infer K extends string}` ? K : never;
// This is equivalent to
// export type AllowedKeys = "key1" | "key2" | "key3"
You can have typescript infer a type from data in a json-file.
import data from "./data.json";
export type AllowedKeys = keyof typeof data["someList"];
// This is equivalent to
// export type AllowedKeys = "#key1" | "#key2" | "#key3"
The resulting d.ts
file looks like this:
import data from "./data.json";
export declare type AllowedKeys = keyof typeof data["someList"];
As far as I know, there's no way to manipulate string literals in typescript (i.e, removing the #
).
See those github issues :
Upvotes: 3