We at Future Studio use TypeScript on the frontend and backend. The backend uses an ORM and related models to interact with data from the database. The database models define all accessible properties that are available in the serialized JSON. The frontend uses this JSON and we want to derive a TypeScript type of the model’s shape. This shape contains all model properties, but not the functions.
This tutorial shows you how to get all class fields and create a TypeScript type from it.
TypeScript Series Overview
- How to Export Transpiled Code From package.json
- Use Nodemon to Restart Your Server on Changes
- How to Allow Trailing Commas (Comma-Dangle) With Typescript-ESLint
- Use SWC to Speed up TypeScript Code
- Fixing Null Type Ignored in Union Type
- How to Remove Index Signature from a Type
- Module Augmentation Overwrites Declarations Instead of Merging Them
- Get All Keys of an Enum
- Get All Values of an Enum
- Using a String as Enum Key
- Understanding “keyof typeof”
- Get Type of Class Properties and Omit Methods
Extract Class Properties in TypeScript
TypeScript can extract properties from a class type and create a new type of it. You must create yourself a helper type that extracts all properties from a class type. Your helper must ignore all Function properties (= class methods).
Here’s the TypeScript type that extracts all properties of a class and creates a new type for them:
type ClassProperties<C> = {
[Key in keyof C as C[Key] extends Function ? never : Key]: C[Key]
}
Now you can use this TypeScript type that extracts all class properties and a create a new type that contains the fields and nothing else. Here’s a code sample using a UserModel
as the origin to extract all properties:
type ClassProperties<C> = {
[Key in keyof C as C[Key] extends Function ? never : Key]: C[Key]
}
class UserModel {
public name!: string
public getName(): string {
return this.name
}
}
export type UserPropertiesType = ClassProperties<UserModel>
// type UserPropertiesType = { name: string; }
The created UserPropertiesType
contains the name
field. It doesn’t have the getName()
method anymore. Sweet!
Remember TypeScript Visibility Keywords
What happens to properties using other visibility keywords than public
? TypeScript comes with the private
, protected
, and public
visibilities. We saw that all public
properties are part of the resulting property’s type. But what happens to protected
and private
properties? Let’s find out!
type ClassProperties<C> = {
[Key in keyof C as C[Key] extends Function ? never : Key]: C[Key]
}
class UserModel {
public name!: string
protected age!: number
private readonly internalNotes: string = ''
public getName(): string {
return this.name
}
}
export type UserPropertiesType = ClassProperties<UserModel>
// type UserPropertiesType = { name: string; }
The UserPropertiesType
type contains only public
properties. private
and protected
properties are not part of the derived type. You must adjust the property visibilities to expose them.
Enjoy extracting properties from TypeScript classes!