Home > Mobile >  Сreate an object of type T from another object that implements type T
Сreate an object of type T from another object that implements type T

Time:05-09

I have the following code:

type T = {
    a: number
    b: string
}

class SomeClass implements T {
    a: number = 1
    b: string= ''
    
    c: boolean = false
}

let object1: SomeClass = new SomeClass()
let object2: T = ???

How can I get a new object from an instance of SomeClass that contains only properties of type T (a,b), without any other SomeClass properties (c)?

CodePudding user response:

Types do not exist at runtime, so you cannot use them for processing an instance. There are various ways in which this could be approached, e.g. if T were a class, possibly its metadata could be emitted and used at runtime to transform the object.

You could also define a function where you pass in the keys and the type system will ensure that only valid keys are used. But making sure that all keys are present is another issue.

function limitProperties<T extends K, K>(
  instance: T,
  ...keys: (keyof K)[]
) {
  // Naive shallow implementation
  const obj = {} as any as K;
  for (const key of keys)
    obj[key] = instance[key]

  return obj;
}

let object1: SomeClass = new SomeClass()
let object2: T = limitProperties(object1, 'a', 'b'); // Adding 'c' causes error

Playground

There also are libraries which usually are used for request validation that can help with this. E.g. with Zod:

import { z } from 'zod';

const t = z.object({
  a: z.number(),
  b: z.string(),
});

type T = z.infer<typeof t>; // Original T derived from object

class SomeClass implements T {
    a: number = 1
    b: string= ''
    
    c: boolean = false
}

let object1: SomeClass = new SomeClass()
let object2: T = t.parse(object1);

Playground (not runnable)

CodePudding user response:

It's called Excess Property Checks which TypeScript does not trigger by default, the base behavior for most interfaces is to see the structure as type contracts or a generic, which only requires partial match.

Although there are certain syntaxes that triggers exact match. It's not being a common paradigm so I would suggest you to not think of things this way (by exact matching) when first getting started.

https://www.typescriptlang.org/docs/handbook/interfaces.html#excess-property-checks

  • Related