Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Class static members type constraint #57422

Closed
6 tasks done
Zamralik opened this issue Feb 16, 2024 · 2 comments
Closed
6 tasks done

Class static members type constraint #57422

Zamralik opened this issue Feb 16, 2024 · 2 comments
Labels
Duplicate An existing issue was already created

Comments

@Zamralik
Copy link

πŸ” Search Terms

class static members type
class static type
class static interface
class static implements
class static members constraint

βœ… Viability Checklist

⭐ Suggestion

Add the ability to type classes static members using the satisfies keyword.

Reuse satisfies because it must not alter the effective type of the class, only constrained it.

πŸ“ƒ Motivating Example

TypeScript let you type constrained instanciated objects.

type Chatty = {
    speak: () => string;
};

class Dog implements Chatty
{
    private name: string;

    public constructor(name: string)
    {
        this.name = name;
    }

    public speak(): string
    {
        return `${this.name} says "Woof!".`;
    }
}

Let's imagine that we want to abstract object serialization, it would be natural to require it to have both a serialize method, and a deserialize static method.

Originally we would have only been able to define serialize as it was impossible to type the static members of a class. Until now!

type Serializable = {
    serialize(): string;
};

type ReversiblySerializable<T> = {
    new(...args: any[]): T & Serializable;
    deserialize(stringified: string): T;
};

class Point satisfies ReversiblySerializable<Point>
{
    public x: number;
    public y: number;

    public constructor(x: number, y: number)
    {
        this.x = x;
        this.y = y;
    }

    public serialize(): string
    {
        return `${this.x},${this.y}`;
    }

    public static deserialize(stringified: string): Point
    {
        const [x, y] = stringified.split(",");

        return new Point(+x, +y);
    }
}

πŸ’» Use Cases

  1. What do you want to use this for?
    Enforce generalized class static members to be properly normalized.

  2. What shortcomings exist with current approaches?
    You cannot type static members cleanly.

  3. What workarounds are you using in the meantime?
    I have a utility function that does nothing for the sole purpose of generating errors in TS in the file where the class is declared rather than where the constructor is used.
    But it pollute the resulting JS code with pointless code at runtime.

// @ts-expect-error: unused parameter because it's not supposed to do anything at runtime.
export function staticImplements<T>(constructor: T): void {}

Example of use:

export class Point { /* ... */ }

staticImplements<ReversiblySerializable<Point>>(Point);
@Zamralik Zamralik changed the title Class static members type Class static members type constraint Feb 16, 2024
@fatcerberus
Copy link

This sounds like #33892.

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Feb 16, 2024
@typescript-bot
Copy link
Collaborator

This issue has been marked as "Duplicate" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale Feb 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants