Skip to content

Expose Self as a type within classes #38426

@lonewarrior556

Description

@lonewarrior556

often when Declaring a class it's very useful to reference the Class itsself as a type internally

For Example

class SomeReallyLongClassNameComponentThing {
  valueA: SomeReallyLongInportedValueA;
  valueB: SomeReallyLongInportedValueb;

  doSomethingWithA(val: SomeReallyLongClassNameComponentThing['valueA']) {}
  doSomethingWithB(val: SomeReallyLongClassNameComponentThing['valueB']) {}
}

It's nice that I can reference the className inside the class Decloration..
During refactoring I can change the type of valueA with a single edit.

however:

  • The name of the class can be long
  • Name of the class is changeable

So we have resorted to making single classes perfile and using this syntax

type Self = SomeReallyLongClassNameComponentThing;
class SomeReallyLongClassNameComponentThing {
  valueA: SomeReallyLongInportedValueA;
  valueB: SomeReallyLongInportedValueb;

  doSomethingWithA(val: Self['valueA']) {}
  doSomethingWithB(val: Self['valueB']) {}
}

Search Terms

Self type in classes, Class Scope Types

Suggestion

It would be awesome if type Self was automatically declared as a type inside the class Declaration..
(or if you could declare Self only in the scope of the class Declaration

ie 1. scoping

export class SomeReallyLongClassNameComponentThingOne {
  type Self = SomeReallyLongClassNameComponentThingOne;
  valueA: SomeReallyLongInportedValueA;
  valueB: SomeReallyLongInportedValueb;

  doSomethingWithA(val: Self['valueA']) {} 
  doSomethingWithB(val: Self['valueB']) {}
}

export class SomeReallyLongClassNameComponentThingTwo {
  type Self = SomeReallyLongClassNameComponentThingTwo;
  valueOne: SomeReallyLongInportedValueOne;
  valueTwo: SomeReallyLongInportedValueTwo;

  doSomethingWithA(val: Self['valueOne']) {}
  doSomethingWithB(val: Self['valueTwo']) {}
}

-ie 2. AutoDeclared

export class SomeReallyLongClassNameComponentThingOne {
  valueA: SomeReallyLongInportedValueA;
  valueB: SomeReallyLongInportedValueb;

  doSomethingWithA(val: Self['valueA']) {} 
  doSomethingWithB(val: Self['valueB']) {}
}

export class SomeReallyLongClassNameComponentThingTwo {
  valueOne: SomeReallyLongInportedValueOne;
  valueTwo: SomeReallyLongInportedValueTwo;

  doSomethingWithA(val: Self['valueOne']) {}
  doSomethingWithB(val: Self['valueTwo']) {}
}

Use Cases

  • Easy Self reference and access to class Types
  • Easier refactoring of Names
  • Scoping of type Variables

Examples

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • 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