0

with typescript interfaces, i'd like to include only the keys that i declare in interface itself.

I defined a Person interface as follows:

interface Person {
    name: string
    surname: string
}

In another snippet i receive a json as follows:

let personFromServer = {
    name: "myName",
    surname: "mySurname",
    age: 16
}
let p : Person = personFromServer;

console.log("I wish p to have only name and surname", p)

When i log the p variable i'd like to have only

{
   name: "myName"
   surname: "mySurname"
}

But i get the age field too:

{
   name: "myName"
   surname: "mySurname"
   age: 16
}

Is it possible to natively accomplish my desired result, in other words just to include the desired keys (and ignoring the extra keys, cause of information overflow)?

Thank you in advance.

  • Interfaces are compile-time constructs; they don't exist at run time. So by the time your code gets that object, that interface is long gone. You could create a `class`, which takes an object as a constructor parameter and sets its properties to those of the object of the same name (there are libraries which do this also). – Heretic Monkey Jan 18 '22 at 18:09

1 Answers1

0

This probably is not a problem. If a property isn't part of the type, then Typescript won't let you access that property. In this case, if you try to access age you will get a type error.

let personFromServer = {
    name: "myName",
    surname: "mySurname",
    age: 16
}
let p: Person = personFromServer;
p.age // Property 'age' does not exist on type 'Person'.(2339)

It's important to remember that Typescript is a compile time tool to allow the developer to write more correct code more quickly. Typescript is not a way to enforce types of objects at runtime.

When compiled, all your above code turns into:

let personFromServer = {
    name: "myName",
    surname: "mySurname",
    age: 16
}
let p = personFromServer;
console.log("I wish p to have only name and surname", p)

So there is no hint left in the executable code that could tell you what should be included and should not.


This might matter if there are security implications. For example, a user may have a hashed password that user is retrieved from the database that you don't want your server to return on its public API. Then you have to do this manually at runtime.

Perhaps something like:

import _ from 'lodash' // use lodash's omit() for simplicity

interface Person {
    name: string
    surname: string
}

interface PersonWithAge extends Person {
  age: number
}

let personFromServer: PersonWithAge = {
    name: "myName",
    surname: "mySurname",
    age: 16
}
let p: Person =  _.omit(personFromServer, 'age')
console.log(p) // only name and surname

Playground

Alex Wayne
  • 178,991
  • 47
  • 309
  • 337