2 ms·
I hear you, but I don’t think this is necessarily true. It does leave type checking to your parsing logic, but the compiler can give you strong guarantees that
by r3trohack3r 3y ago
I hear you, but I don’t think this is necessarily true. It does leave type checking to your parsing logic, but the compiler can give you strong guarantees that you’re being defensive about untrusted structured data.
I use a JsonObject to do type narrowing and generate appropriate error messages when I receive invalid data over the wire: https://www.npmjs.com/package/@retrohacker/json-types https://www.npmjs.com/package/@retrohacker/json-types
In every codebase I’ve added this to, I’ve found invalid parsing logic.
I feel like this type, or something similar, should be bundled in the official TypeScript project. That untested data comes out as “any” is not a good developer experience in my opinion.
And “unknown” is basically broken for type narrowing.
- madeofpalk 3y ago> And “unknown” is basically broken for type narrowing. How? Typescript 4.9 improved it for type narrowing significantly. https://devblogs.microsoft.com/typescript/announcing-typescript-4-9/#in-narrowing https://devblogs.microsoft.com/typescript/announcing-typescr... Last weekend I actually hacked an an experiment to codegen narrowing unknown to a specific type and it works pretty well https://github.com/joshhunt/codegen-json-validator-experiment/blob/main/output.ts https://github.com/joshhunt/codegen-json-validator-experimen...
- r3trohack3r 3y agoI haven't worked much in typescript over the last 10 months, but last time I tried type narrowing on untrusted data typecast to unknown I ran into a handful of problems documented here: https://github.com/microsoft/TypeScript/issues/25720 https://github.com/microsoft/TypeScript/issues/25720 Working with untrusted types in a GraphQL project lead me to creating that JsonObject module. I wrote up what I was thinking at the time here: http://www.blankenship.io/essays/2022-12-01/ http://www.blankenship.io/essays/2022-12-01/ Maybe this has improved.
- madeofpalk 3y agoYes. The main one is `foo in obj` now correctly narrows to `unknown & { foo: unknown }`. This allows you to correctly narrow an unknown to a fully typed object, as my code sample shows :)
- beders 3y agoThe compiler can't help you at all when reading and validating data at runtime. You mean you could use a library that helps you with checking the shapes?
- r3trohack3r 3y agoThe compiler will tell you when you are accessing data you haven't validated yet. Using the json-types module above, you assign your incoming json object to the JsonObject type. Then you type narrow by validating the payload contains the properties you are using. So you can: const user = (await body.json()) as JsonObject; // This is properly type narrowed and will work if (typeof user.emailAddress === "string") { // do something with user.emailAddress } // The compiler will let you know you can't trust // user.name to be a string at this point. This // would have generated an exception at runtime // for a malformed payload if the compiler didn't // catch it. user.username.split(" ") // You can also do type narrowing with early returns if(typeof user.age !== number) { return new Error("user.age is expected to be a number"); } // You can now use user.age with type safety ```