DEV Community

Luke Miles
Luke Miles

Posted on • Edited on

4 1

Closest thing to structs / dataclasses / records in typescript with default values

(You may have also googled for

  • react typescript default props,
  • typescript default values for interface, or
  • typescript default destructured args.)

Data-only classes are easy to understand; you can add 'methods' (functions taking them) to them when you import them; there is no worries of using this wrong and it's usually easier to figure out if they are modified (partly because you can make a function argument const a bit more easily than with this); you know that they have a fixed set of attributes; methods and data are easily distinguishable. There's a reason structs fundamental in golang and something like structs has been added or always existed in python, swift, scala, etc.

So how do we do it in typescript? One mediocre option is to use regular classes and restrain yourself to avoid methods. I won't go into detail on that or other mediocre options that require repeating yourself three times. Below is a pretty good option, and now my go-to for structs in typescript.

Use a function to make your struct and Required<> for the exported type.

interface PartialCar {
    model: string
    owner: [string, string]
    year?: number
    make?: string
    staysNull?: string | null
}
export type Car = Required<PartialCar>
export function newCar(args: PartialCar): Car {
    return {
        year: 1999,
        make: "toyota",
        staysNull: null,
        ...args,
    }
}
export function print(c: Car): void {
    console.log(`${c.owner}'s gorgeous ${c.year} ${c.model} from ${c.make}`)
}
function example(a: number, b: number, c: Car): number {
    const c = newCar(pc)
    return a + b + c.year
}
function caller() {
    return example(5, 10, newCar({ model: 'ford', owner: ['bob', 'bill'] }))
}
Enter fullscreen mode Exit fullscreen mode

Ezpz. This also shows you how to do default/optional destructured parameters with thorough type hinting.

Edit: I realized a react example might be useful:

unction Car(props: {
    model: string
    owner: [string, string]
    year?: number
    make?: string
}): JSX.Element {
    const P = {
        year: 1999,
        make: "toyota",
        ...props
    }
    const length = P.make.length // passes strict null checks!
    return <div>
        {P.owner[0]} {P.owner[1]}{"'s"} {P.make} {P.model} goes vroom with {length} letters.
    </div>
}```



Using this in the codebase of splashcall rn.
Enter fullscreen mode Exit fullscreen mode

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more →

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more