-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JSON type #27930
Comments
@weswigham refinements on |
What are the use cases for writing JSON strings in code instead of writing them as parsed literals? |
@RyanCavanaugh I have plenty of mock data for tests as JSON in strings, when you receive response from and API it could be JSON in a string, when you read from a file it could be Doubly, triply, etc. serialized JSON is another example. '{"body": "{\"userId\": 123}"}' // JSON {body: JSON {userId: number}} |
What I mean is, if you're writing the code, why are you writing them in the error-prone |
@RyanCavanaugh I am not, but sometimes you receive your data in that form and you have to deal with it. For example, here is a typical AWS SQS response example: {
"Messages": [
{
"Body": "{\n \"Message\" : \"{\\\"assetId\\\":14,\\\"status\\\":\\\"Uploading\\\",\\\"updatedAt\\\":\\\"2018-10-16T08:47:43.538Z\\\"}\",\n }"
}
]
} (I have removed some fields for brevity. Also, I hope all the escapings are correct. :) ) The above is basically dobly-serialized JSON in interface Response {
Messages: ({
Body: JSON {
Message: JSON {
assetId: number;
status: 'Queued' | 'Uploading' | 'Error' | 'Done';
updatedAt: string;
}
}
})[];
} |
Makes sense - but in that case, we can't really do any valuable typechecking of that JSON at compile-time. Or are you saying you're copying the JSON responses into your test files? Just trying to understand |
Sure, but code can be annotated at dev time so developer can get all the code completion and error messages that are obvious from static code analysis. For example: JSON.parse(JSON.parse(JSON.parse(message).Body).Message).assetId; // OK
JSON.parse(JSON.parse(JSON.parse(message).Body).Message).oops; // Error: ...
Yes. |
So you're saying it'd be useful coupled with a declare function parse<T>(string: JSON T): T; |
@weswigham Exactly! interface GlobalJSON {
parse: <T>(str: JSON T) => T;
stringify: <T>(obj: jsontype T) => T;
} |
Along the lines of what people have said in #4895, you can get pretty close with branded strings today: type JSONString<T> = string & { " __JSONBrand": T };
function parse<T>(str: JSONString<T>): T { return JSON.parse(str as string) as any; };
let responseBody = '{"ping": "pong"}' as JSONString<{ping: 'pong'}>;
parse(responseBody).ping; // OK there's no automatic creation of them and no automatic validation that your string actually meets the constraint you want the type to imply, but you can flow the type around, at least. |
@weswigham How would you annotate function stringify<T>(obj: T): JSON<T> { return JSON.stringify(obj); } |
BTW, create this tiny NPM package if anyone needs branded JSON strings: |
It is faster to use So this feature is now a bit more useful (although it is better if the compiler will generate the |
Search Terms
Suggestion
Type annotation for JSON in a string.
Use Cases
Let's say you have a string which contains valid JSON object, like so:
How can you type annotate the
json
variable? Currently, you can mark it as astring
:Instead there could be some TypeScript language feature that helps with typing JSON in a string more precisely, for example:
Examples
Specify that string contains valid JSON.
Add typings to an HTTP response body.
Add type safety to
JSON.parse()
method.JSON cannot contain complex types.
Doubly serialized JSON.
Get type of serialized JSON string using
jsontype
keyword.Specify that variable is JSON-serializable.
Checklist
My suggestion meets these guidelines:
Syntax Alternatives
The text was updated successfully, but these errors were encountered: