source

TypeScript에서 중첩된 클래스를 만들 수 있습니까?

bestscript 2023. 3. 1. 11:17

TypeScript에서 중첩된 클래스를 만들 수 있습니까?

TypeScript에 클래스를 중첩하는 방법이 있습니까?예: 다음과 같이 사용하고 싶습니다.

var foo = new Foo();
var bar = new Foo.Bar();

현대의 TypeScript에는 네스트된 클래스를 만드는 데 사용할 수 있는 클래스 식이 있습니다.예를 들어 다음 작업을 수행할 수 있습니다.

class Foo {
    static Bar = class {
        
    }
}

// works!
var foo = new Foo();
var bar = new Foo.Bar();

다음은 클래스 표현을 사용한 보다 복잡한 사용 사례입니다.

를 통해 내부 클래스에서private외부 계급의 멤버들

class classX { 
    private y: number = 0; 

    public getY(): number { return this.y; }

    public utilities = new class {
        constructor(public superThis: classX) {
        }
        public testSetOuterPrivate(target: number) {
            this.superThis.y = target;
        }
    }(this);    
}

const x1: classX = new classX();
alert(x1.getY());

x1.utilities.testSetOuterPrivate(4);
alert(x1.getY());

코드펜

컴파일 오류를 수신하지 않고 내보낸 클래스에서 이 작업을 수행할 수 없습니다. 대신 네임스페이스를 사용했습니다.

namespace MyNamespace {
    export class Foo { }
}

namespace MyNamespace.Foo {
    export class Bar { }
}

형식 선언 파일의 컨텍스트에 있는 경우 클래스 및 네임스페이스를 혼합하여 이 작업을 수행할 수 있습니다.

// foo.d.ts
declare class Foo {
  constructor();
  fooMethod(): any;
}

declare namespace Foo {
  class Bar {
    constructor();
    barMethod(): any;
  }
}

// ...elsewhere
const foo = new Foo();
const bar = new Foo.Bar();

이 답변은 @basarat의 답변 위에 구축되는 TypeScript의 외관상 중첩된 클래스 구현에 관한 것입니다.

정적 중첩 클래스의 유형을 만드는 방법Bar액세스 가능(@PeterMoore가 지적한 대로) 네스트된 클래스의 유형을 네임스페이스에 선언합니다.그래야 지름길을 이용할 수 있다.Foo.Bar. 이동 유형별typeof Foo.Bar.prototype선언된 네임스페이스의 유형으로 변환하기 때문에 식을 반복할 필요가 없습니다.

class Foo {
    static Bar = class {
        
    }
}

declare namespace Foo {
    type Bar = typeof Foo.Bar.prototype
}

// Now we are able to use `Foo.Bar` as a type
let bar: Foo.Bar = new Foo.Bar()

정적 클래스의 경우 다음 구현이 더 우아할 수 있습니다.단, 이것은 비정적 클래스에서는 동작하지 않습니다.

class Foo { }

namespace Foo {
    export class Bar { }
}

let bar: Foo.Bar = new Foo.Bar()

클래스를 내보내려면 클래스 및 네임스페이스가 선언된 후 export 문을 추가할 수 있습니다.export default Foo또는export { Foo }.

비 스태틱 네스트클래스에서도 같은 것을 실현하려면 , 다음의 예를 참조해 주세요.

class Foo {
    Bar = class {
        
    }
}

declare namespace Foo.prototype {
    type Bar = typeof Foo.prototype.Bar.prototype
}

let foo: Foo = new Foo()
let bar: Foo.prototype.Bar = new foo.Bar()

도움이 되었으면 합니다.

기능:

  • 새 내부 클래스 인스턴스 만들기
  • 외부 클래스 인스턴스/프로토타입 멤버 액세스
  • 인터페이스 구현
  • 데코레이터 사용

사용 사례

export interface Constructor<T> {
    new(...args: any[]): T;
}

export interface Testable {
    test(): void;
}

export function LogClassName<T>() {
    return function (target: Constructor<T>) {
        console.log(target.name);
    }
}

class OuterClass {
    private _prop1: string;

    constructor(prop1: string) {
        this._prop1 = prop1;
    }

    private method1(): string {
        return 'private outer method 1';
    }

    public InnerClass = (
        () => {
            const $outer = this;

            @LogClassName()
            class InnerClass implements Testable {
                private readonly _$outer: typeof $outer;

                constructor(public innerProp1: string) {
                    this._$outer = $outer;
                }

                public test(): void {
                    console.log('test()');
                }

                public outerPrivateProp1(): string {
                    return this._$outer._prop1;
                }
                
                public outerPrivateMethod1(): string {
                    return this._$outer.method1();
                }
            }
            return InnerClass;
        }
    )();
}

const outer = new OuterClass('outer prop 1')
const inner = new outer.InnerClass('inner prop 1');

console.log(inner instanceof outer.InnerClass); // true 
console.log(inner.innerProp1); // inner prop 1
console.log(inner.outerPrivateProp1()); // outer prop 1
console.log(inner.outerPrivateMethod1()); // private outer method 1

언급URL : https://stackoverflow.com/questions/32494174/can-you-create-nested-classes-in-typescript