Sử dụng mảng đã nhập TypeScript


96

Tôi có một định nghĩa lớp TypeScript bắt đầu như thế này;

module Entities {          

    export class Person {
        private _name: string;
        private _possessions: Thing[];
        private _mostPrecious: Thing;

        constructor (name: string) {
            this._name = name;
            this._possessions = new Thing[100];
        }

Có vẻ như một mảng kiểu Thing không được dịch chính xác sang kiểu mảng Javascript tương ứng. Đây là một đoạn mã từ JavaScript đã tạo:

function Person(name) {
    this._name = name;
    this._possessions = new Entities.Thing[100]();
}

Đang thực thi mã có chứa đối tượng Person, hãy ném một ngoại lệ khi cố gắng khởi tạo trường _possession:

Lỗi là "0x800a138f - Lỗi thời gian chạy Microsoft JScript: Không thể nhận giá trị của thuộc tính '100': đối tượng là null hoặc không xác định".

Nếu tôi thay đổi kiểu _possession thành any[] và khởi tạo _possession với new Array()ngoại lệ sẽ không được ném ra. Tôi đã bỏ lỡ điều gì đó?

Câu trả lời:


120

Bạn có lỗi trong cú pháp của mình ở đây:

this._possessions = new Thing[100]();

Điều này không tạo ra một "mảng của mọi thứ". Để tạo một mảng, bạn chỉ cần sử dụng biểu thức mảng:

this._possessions = [];

Trong số phương thức khởi tạo mảng nếu bạn muốn đặt độ dài:

this._possessions = new Array(100);

Tôi đã tạo một ví dụ làm việc ngắn gọn mà bạn có thể thử trong sân chơi .

module Entities {  

    class Thing {

    }        

    export class Person {
        private _name: string;
        private _possessions: Thing[];
        private _mostPrecious: Thing;

        constructor (name: string) {
            this._name = name;
            this._possessions = [];
            this._possessions.push(new Thing())
            this._possessions[100] = new Thing();
        }
    }
}

2
nó không cố định độ dài, mà nên định vị trước mảng
Sebastian

tại sao bạn không thể làm private _possessions: Thing[] : []; trong định nghĩa lớp?
SuperUberDuper

54

Bạn có thể thử một trong hai cách này. Họ không cho tôi lỗi.

Nó cũng là phương thức được gợi ý từ typecript để khai báo mảng .

Bằng cách sử dụng Array<Thing>nó đang sử dụng các generic trong bảng chữ. Nó tương tự như yêu cầu List<T>mã trong c #.

// Declare with default value
private _possessions: Array<Thing> = new Array<Thing>();
// or
private _possessions: Array<Thing> = [];
// or -> prefered by ts-lint
private _possessions: Thing[] = [];

hoặc là

// declare
private _possessions: Array<Thing>;
// or -> preferd by ts-lint
private _possessions: Thing[];

constructor(){
    //assign
    this._possessions = new Array<Thing>();
    //or
    this._possessions = [];
}

3
Để định vị trước kích thước, hãy sử dụng new Array<Thing>(100).
Doug Domeny

1
bạn cũng có thể sử dụng ... <Thing> []
danday74

@ danday74 - Tôi đã cập nhật để bao gồm phương thức của bạn, nó là mặc định khi sử dụng cấu hình ts-lint được đề xuất / mới nhất.
Kieran

9

Bản dịch là chính xác, việc nhập biểu thức thì không. TypeScript đang nhập sai biểu thức new Thing[100]dưới dạng một mảng. Nó sẽ là một lỗi đối với chỉ mục Thing, một hàm khởi tạo, sử dụng toán tử chỉ mục. Trong C #, điều này sẽ phân bổ một mảng gồm 100 phần tử. Trong JavaScript, điều này gọi giá trị tại chỉ mục 100 của Thingnhư thể là một hàm tạo. Vì các giá trị undefinedđó là nó làm tăng lỗi bạn đã đề cập. Trong JavaScript và TypeScript mà bạn muốn new Array(100)thay thế.

Bạn nên báo cáo đây là một lỗi trên CodePlex.


1
Tôi không muốn Mảng mới (100). Tôi muốn một mảng Thing đã nhập. Tôi không biết liệu đây có phải là một lỗi hay chỉ là sự hiểu sai của tôi về thông số tài liệu.
Klaus Nji
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.