Bạn có thể tạo các lớp lồng nhau trong TypeScript không?


Câu trả lời:


132

Bắt đầu với TypeScript 1.6, chúng ta có các biểu thức lớp ( tham chiếu ).

Điều này có nghĩa là bạn có thể làm như sau:

class Foo {
    static Bar = class {

    }
}

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

1
ví dụ này không hoạt động trong Typecript 1.6.3: Lỗi TS4028 Thuộc tính tĩnh công khai 'Thanh' của lớp đã xuất có hoặc đang sử dụng tên riêng '(Lớp ẩn danh)'.
Sergey

1
@Sergey Tôi đã gặp vấn đề tương tự nên đã bắt đầu sử dụng không gian tên theo câu trả lời của tôi bên dưới.
Dan Def

Có cách nào để tạo giao diện bên trong một lớp không? tức là nếu chúng ta muốn Thanh đó sẽ là một giao diện
RoG

@LittaHervi - Một trường hợp sử dụng sẽ trả về một triển khai riêng của một giao diện bên ngoài, ví dụ, từ một phương thức gốc. Một ví dụ khác từ Java (và các trình khác) là các trình vòng lặp yêu cầu quyền truy cập đặc quyền vào các biến thành viên của lớp chứa chúng và thông qua các quy tắc phạm vi tự động làm như vậy, nhưng bạn không bao giờ muốn chúng được xuất và khởi tạo trực tiếp.
Dave

31

Đây là một trường hợp sử dụng phức tạp hơn bằng cách sử dụng các biểu thức lớp .

Nó cho phép lớp bên trong truy cập các privatethành viên của lớp bên ngoài.

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

codepen


3
@RyanCavanaugh Khả năng truy cập các thành viên riêng tư bên trong một biểu thức lớp "bên trong" có phải là một lỗi không?
bnieland 25/07/17

5
Tôi đã xác minh đây là cách sử dụng đúng với nhóm TypeScript. github.com/Microsoft/TypeScript/issues/…
bnieland

1
có thể nó truy cập ngữ cảnh gốc mà không chuyển trực tiếp điều này không?
shabunc

@shabunc không theo hiểu biết của tôi
bnieland

1
Chính xác những gì tôi đang tìm kiếm, cảm ơn bạn!
Philippe

19

Tôi không thể làm cho điều này hoạt động với các lớp đã xuất mà không gặp lỗi biên dịch, thay vào đó tôi đã sử dụng không gian tên :

namespace MyNamespace {
    export class Foo { }
}

namespace MyNamespace.Foo {
    export class Bar { }
}

Tương tự. 'Foo' chỉ đề cập đến một loại, nhưng đang được sử dụng như một không gian tên ở đây.
Will Beason

12

Nếu bạn đang ở trong ngữ cảnh của tệp khai báo kiểu, bạn có thể thực hiện việc này bằng cách trộn các lớp và không gian tên:

// 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();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.