1

I'm working with an existing codebase that I'm introducting TypeScript too.

say I've got some frontend code that looks like this:

const res = await fetch('/api/user'); 
const user = res.json(); 

And my User interface looks like:

interface User {
    name: string; 
    age; 
}

I could just coerce the response from .json()

const user = res.json() as User; 

But there is no guarantee that the backend is actually sending me the correct response and I'd rather be aware of that upfront. So my preference is to use a parsing function like:

function parseUser(input: any) : User {
    try {
        const user = {
           name: input.name, 
           age: input.age
        }; 

        if (typeof user.name !== 'string' || typeof user.age !== 'number') {
             throw new Error("Object had correct field, but wrong value types"); 
        }
        return user; 
    } catch(err) {
         throw new Error("Error parsing user"); 
    }
}

Now the thing is - for objects with much larger schemas, this would be hellish to write.

Is there some kind of utilty that can create these functions from my interface definitions?

0

The ts-interface-builder and ts-interface-checker libraries work very well for this. Here's how I set mine up:

1. Add the dependencies as dev dependencies

npm i -D ts-interface-builder ts-interface-checker

2.Define your types in src/types

//src/types/User.ts

export interface User {
    name: string; 
    age; 
}

3. Add a src/ti folder

The next step will fail if this folder doesn't already exist.

4. Add buildCheckers npm script

//package.json 

    "buildCheckers": "ts-interface-builder -o src/ti src/types/*.ts",

5. To create a new parsing function:

  1. run npm run buildCheckers (I don't know how to get this command to run in watch mode).
  2. Create a parsing function as follows, (I put the parsing function in the same file as the interface definition)
//src/types/User.ts
import userTypes from "../ti/User-ti";
const {  User} = createCheckers(userTypes);

//Our existing interface we created in step 2
export interface User {
    name: string; 
    age; 
}

export function parseUser(item: any): User {
    try {
        User.check(item); 
        return item as User;
    } catch (err) {
        throw new Error ("Error instantiating object to type User"); 
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.