0

Is there a best way to check an object against a typescript infterface?

I am working between two schemas, where one extends the other. I need to convert the extension back to base, and am doing so by deleting props from the extension to shape it to the original base class. An example:

interface Base {
  prop1: string
  prop2?: string
  prop3?: string
}

interface Extended extends Base {
  prop4: string
  prop5: string
}

So in order to get Extended back to Base, I need to delete props prop4 and prop5

This is of course easy enough to do, but, I need to ensure that the final result conforms to the Base class, since deleting props does not tell the compiler anything, and the extension will pass the Base type check.

I have looked at using a type guard, and other alternatives, however, I have not found a way to do this which accommodates for the optional properties found in Base, or a seemingly efficient way to do it.

Here is a basic plan for the type guard as well as handling optional props:

function isBase(arg: any): arg is Base {
  return arg
    && arg.prop1
    && (arg.prop2 || true)
    && (arg.prop3 || true)
}

Besides being a lot of work for a lot of props, it's brittle. Soon as Base changes, this technique no longer works as intended. I feel like there is (should be) some Typescript way via utility types that could check the props against the Base interface, so it will always work as intended.

Update

I found this. Looks very close but could not get it working with interfaces.

3
  • Utility types wouldn't work since interface are design-time types and not run-time types, therefore you'd need to have type-guard code compiled in the first place, which will then run. Type guards are the only solution AFAIK. Commented Sep 9, 2019 at 21:02
  • "I need to convert the extension back to base" Why? If the type extends a base then that type can be treated as a base, you don't need to remove properties... Commented Sep 9, 2019 at 21:43
  • The extension is used for client side purposes, and the base is what is stored in the db. So while it can be treated as the base, I do not want to store the additional data the extension holds (in the db), and want to check that is the case before sending it across the wire. Commented Sep 9, 2019 at 21:57

1 Answer 1

1

If you need to keep Base as a standalone property, using composition instead of inheritance might be a better approach, for instance:

interface Base {
  prop1: string
  prop2?: string
  prop3?: string
}

interface Extended {
  data: Base
  prop4: string
  prop5: string
}

Do whatever is needed with Extended but only send data to database.

Sign up to request clarification or add additional context in comments.

1 Comment

This looks like a good technique. Although that means all uses of Extended class would need to be updated to have the data prop that consists of Base.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.