Skip to content

Allow class decorators to add static properties. #40805

Closed
@Griffork

Description

@Griffork

Search Terms

Class, decorators, typing.

Suggestion

I have a decoator which is typed like so to add a static method to a decorated class. I would like the decorator's typing information to be evaluated and added to the class' typing information.

Decorator typing information (Biscuit is the name of my engine, don't judge I'm not good at naming things):

type ConstructArgs<T> = T extends (new (...args: infer C) => any)?C: never;
type Prototype<T> = (Function & { prototype: T });

//First set of params are the ones supplied in the decorator, like: @BiscuitObject(common);
declare function BiscuitObject<SerialiseType extends Object>(datatype: SerialiseType): (
		//Second set of params are the class the decorator is decorating, in this case the BiscuitObject.
		<
			BiscuitClass extends Function & { prototype: Object },
			Biscuit extends Prototype<BiscuitClass>,
			ConstructorArguments extends ConstructArgs<Biscuit>,
		>
			(biscuit: BiscuitClass) => BiscuitClass & {
				//We return a deserialise function that takes some data and converts it
                // into a new object of this class type.
				deserialise: (object: SerialiseType, ...args: ConstructorArguments) =>	Biscuit;
	});

Example code:

class BDataType {
    tell!: string;
    constructor(tell: string) {
        this.tell = tell;
    }
}

@BiscuitObject(BDataType)
class B {
    tell: string;
    param: string;
    constructor(param: string) {
        this.param = param;
        this.tell = "hi";
    }
    serialise() {
        return new BDataType(this.tell);
    }
	method() {
		console.log(this.tell, this.param);
	}
}

B.deserialise(new BDataType("world"), "hello").method(); //This line errors currently.

https://www.typescriptlang.org/play?#

Use Cases

I want to use this to automate the addition of several common static functions that I use across about 20 different classes in my codebase.

Checklist

My suggestion meets these guidelines:

  • [y] This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • [y] This wouldn't change the runtime behavior of existing JavaScript code
  • [y] This could be implemented without emitting different JS based on the types of the expressions
  • [y] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • [y] This feature would agree with the rest of TypeScript's Design Goals.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions