본문 바로가기

개발하자

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

반응형

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();



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

namespace MyNamespace {
    export class Foo { }
}

namespace MyNamespace.Foo {
    export class Bar { }
}



다음은 을 사용한 보다 복잡한 사용 사례입니다.

의 구성원에 액세스할 수 있습니다

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());

코드펜




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

// 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();



이 답변은 중첩된 클래스에 대한 것입니다.

정의(정적)

정적 중첩 클래스 정의는 다음 두 가지 방법으로 수행할 수 있습니다.

  1. 옵션 1: 클래스 내부에 중첩된 클래스를 정의합니다. 형식은 선언으로 선언됩니다.
  2. 옵션 2: 선언 병합을 사용하여 키워드를 사용하여 네임스페이스 내에 중첩된 클래스를 정의합니다.
옵션 1: 내부 클래스 구현

모든 클래스는 하나의 블록, 즉 클래스 선언에서 구현됩니다.

class Foo {
    static Bar = class { }
}

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

let bar: Foo.Bar = new Foo.Bar()
옵션 2: 네임스페이스 내부 구현

정적 클래스의 경우 다음 구현이 일부에게는 더 우아할 수 있습니다. 단점은 이 방법이 정적이 아닌 중첩 클래스에서는 작동하지 않는다는 것입니다.

class Foo { }

namespace Foo {
    export class Bar { }
}

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

정의(비정적)

매끄러운 비정적 중첩 클래스를 만들려면 중첩 클래스가 정적이 아님을 나타내는 데 사용할 수 있습니다.

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


반응형