{"author_link":"\/users\/eckkert","author_name":"Eckkert","author_uid":"eckkert","comments":[],"epoch":1618379093,"event":"LD48","format":"md","ldjam_node_id":238063,"likes":3,"metadata":{"p_key":"152528","p_author":"Eckkert","p_authorkey":"1186175","p_urlkey":"369795","p_title":"Use our Code #5: A Little Typing can Save a Lot of Typing","p_cat":"LDJam ","p_event":"LD48","p_time":"1618379093","p_likes":"3","p_comments":"0","p_status":"WAYBACK","us_key":"1186175","us_name":"Eckkert","us_username":"eckkert","event_start":"1619222400","event_key":"109","event_name":"Ludum Dare 48"},"node":{"_collation":{"body_sanitizer":"TextUtils::SanitizeHTML via existing importer","event":"LD48","removed_author":false},"_superparent":233335,"_trust":3,"author":186175,"body":"Our team is developing [a new WebGL enigne](https:\/\/github.com\/Atomotron\/archimedes2) for this jam. In the process, I kept running in to cases where I wanted to check types, to provide helpful error messages if a complex data structure was mis-assembled by a caller. The ultimate solution to this problem is to use something like TypeScript, but since we wanted to use pure JS for familiarity's sake, it seemed like a good idea to write a typechecking helper. Hopefully, this can save you a little time in your own project.\n\nThe following routine takes object specifications like this:\n```javascript\nconst SHAPE = {\n    name: \"string\",\n    shader: \"?object\",\n    uniforms: \"?object\",\n    draw: \"function\",\n}```\n\nThe check can be performed with a simple call, which returns a boolean:\n```javascript\nconst is_good = shapeCheck(\n    x, \/\/ the untrusted object\n    SHAPE, \/\/ the type schema\n);```\n\nIt supports nullability with the `?` prefix, but it does not support multi-level deep introspection. (That would be a natural addition, but it wasn't needed at the time.) Here's the snippet:\n\n```javascript\nfunction shapeCheck(x,shape) {\n    let good = true;\n    for (const name in shape) {\n        if (typeof x[name] === \"undefined\") {\n            good = false;\n            console.error(x,\"missing\",name);\n            continue;\n        } \n        if (shape[name].startsWith(\"?\")) {\n            if (x[name] === null ||\n                typeof x[name] === shape[name].slice(1)) continue;\n        } else {\n            if (typeof x[name] === shape[name]) continue;\n        }\n        console.error(x,`has wrong type on ${name}: should be`,shape[name]);\n        good = false;\n    }\n    return good;\n}```\n\nIt's designed to exit late, so that as many errors are found as possible. Happy coding!\n\nPrevious *Use our Code* posts:\n1. [Better errors for shader compilation](https:\/\/ldjam.com\/events\/ludum-dare\/48\/$235994\/use-our-code-1-shader-compiler-with-better-errors)\n2. [WebGL Type Info](https:\/\/ldjam.com\/events\/ludum-dare\/48\/$235994\/use-our-code-2-webgl-type-info-and-some-bad-engineering)\n3. [Matrix pretty printing](https:\/\/ldjam.com\/events\/ludum-dare\/48\/$235994\/use-our-code-3-nice-matrix-formatting\/edit)\n4. [Math Library API Design](https:\/\/ldjam.com\/events\/ludum-dare\/48\/$235994\/use-our-code-4-the-many-faces-of-vector-addition\/edit)","comments":0,"created":"2021-04-14T05:36:17Z","files":[],"files-timestamp":0,"id":238063,"love":3,"love-timestamp":"2021-04-14T13:33:03Z","meta":[],"modified":"2021-04-14T13:33:03Z","name":"Use our Code #5: A Little Typing can Save a Lot of Typing","node-timestamp":"2021-04-14T05:48:10Z","parent":235994,"parents":[1,5,9,233335,235994],"path":"\/events\/ludum-dare\/48\/inner-pieces\/use-our-code-5-a-little-typing-can-save-a-lot-of-typing","published":"2021-04-14T05:44:53Z","scope":"public","slug":"use-our-code-5-a-little-typing-can-save-a-lot-of-typing","subsubtype":"","subtype":"","type":"post","version":719065},"node_metadata":{"n_key":"238063","n_urlkey":"369795","n_parent":"235994","n_path":"\/events\/ludum-dare\/48\/inner-pieces\/use-our-code-5-a-little-typing-can-save-a-lot-of-typing","n_slug":"use-our-code-5-a-little-typing-c","n_type":"post","n_subtype":"","n_subsubtype":"","n_author":"186175","n_created":"1618378577","n_modified":"1618407183","n_version":"719065","n_status":"WAYBACK"},"source_url":"https:\/\/ldjam.com\/events\/ludum-dare\/48\/inner-pieces\/use-our-code-5-a-little-typing-can-save-a-lot-of-typing","text":"Our team is developing [a new WebGL enigne](https:\/\/github.com\/Atomotron\/archimedes2) for this jam. In the process, I kept running in to cases where I wanted to check types, to provide helpful error messages if a complex data structure was mis-assembled by a caller. The ultimate solution to this problem is to use something like TypeScript, but since we wanted to use pure JS for familiarity's sake, it seemed like a good idea to write a typechecking helper. Hopefully, this can save you a little time in your own project.\n\nThe following routine takes object specifications like this:\n```javascript\nconst SHAPE = {\n    name: \"string\",\n    shader: \"?object\",\n    uniforms: \"?object\",\n    draw: \"function\",\n}```\n\nThe check can be performed with a simple call, which returns a boolean:\n```javascript\nconst is_good = shapeCheck(\n    x, \/\/ the untrusted object\n    SHAPE, \/\/ the type schema\n);```\n\nIt supports nullability with the `?` prefix, but it does not support multi-level deep introspection. (That would be a natural addition, but it wasn't needed at the time.) Here's the snippet:\n\n```javascript\nfunction shapeCheck(x,shape) {\n    let good = true;\n    for (const name in shape) {\n        if (typeof x[name] === \"undefined\") {\n            good = false;\n            console.error(x,\"missing\",name);\n            continue;\n        } \n        if (shape[name].startsWith(\"?\")) {\n            if (x[name] === null ||\n                typeof x[name] === shape[name].slice(1)) continue;\n        } else {\n            if (typeof x[name] === shape[name]) continue;\n        }\n        console.error(x,`has wrong type on ${name}: should be`,shape[name]);\n        good = false;\n    }\n    return good;\n}```\n\nIt's designed to exit late, so that as many errors are found as possible. Happy coding!\n\nPrevious *Use our Code* posts:\n1. [Better errors for shader compilation](https:\/\/ldjam.com\/events\/ludum-dare\/48\/$235994\/use-our-code-1-shader-compiler-with-better-errors)\n2. [WebGL Type Info](https:\/\/ldjam.com\/events\/ludum-dare\/48\/$235994\/use-our-code-2-webgl-type-info-and-some-bad-engineering)\n3. [Matrix pretty printing](https:\/\/ldjam.com\/events\/ludum-dare\/48\/$235994\/use-our-code-3-nice-matrix-formatting\/edit)\n4. [Math Library API Design](https:\/\/ldjam.com\/events\/ludum-dare\/48\/$235994\/use-our-code-4-the-many-faces-of-vector-addition\/edit)","title":"Use our Code #5: A Little Typing can Save a Lot of Typing","wayback_source":[]}