2015-10-13 20 views
8

phép nói rằng tôi có một lớp cơ sở với một số dataItems tài sản đó là hàng loạt các DataItem:Nhận kiểu của một biến và tạo thể hiện mới của loại hình này

export class BaseClass{ 
    dataItems:DataItems[]; 
} 

Sau đó, tôi có một vài lớp mà mở rộng BaseClass và dataItems của họ thuộc tính là một mảng của một số lớp mở rộng DataItems:

export class BetterClass extends BaseClass{ 
    dataItems:BetterDataItems[]; 
} 

export class BestClass extends BaseClass{ 
    dataItems:BestDataItems[]; 
} 

Bây giờ tôi muốn thêm một phương thức trong BaseClass để tạo dataItems và thêm chúng vào mảng. Nó sẽ có thể làm tất cả điều này trong BaseClass? Tôi cần tạo ra thể hiện của BetterDataItems hoặc BestDataItems, tùy thuộc vào lớp được sử dụng.

Tại thời điểm này tôi chỉ đơn giản là thêm vào:

dataItemType: typeof DataItem; 

tài sản để BaseClass và trong mỗi lớp kéo dài BaseClass tôi ghi đè biến này với đúng loại mục dữ liệu:

trong BetterClass:

dataItemType: typeof BetterDataItem = BetterDataItem; 

trong BestClass:

dataItemType: typeof BestDataItem = BestDataItem; 
.210

Và sau đó, trong BaseClass Tôi làm điều này:

var dataItem = new this.dataItemType(); 

này hoạt động tốt nhưng câu hỏi của tôi là - nó sẽ có thể để tránh việc dataItemType tài sản ở tất cả? Tôi có thể tìm thấy loại mảng dataItems và tạo một phiên bản mới không?

Cảm ơn!

Trả lời

4

nguyên cảo 1,6 mã:

class DataItems { 

} 

class BaseClass { 
    dataItems:DataItems[]; 
    dataItemType: typeof DataItems = DataItems; 
} 

biên dịch để:

var DataItems = (function() { 
    function DataItems() { 
    } 
    return DataItems; 
})(); 
var BaseClass = (function() { 
    function BaseClass() { 
     this.dataItemType = DataItems; 
    } 
    return BaseClass; 
})(); 

Và bạn có thể thấy rằng thông tin kiểu cho dataItems tài sản bị mất trong BaseClass. Đó là cách trình biên dịch TypeScript hoạt động. It does not support runtime checking. Vì vậy, câu trả lời cho câu hỏi của bạn là không.


workaround của bạn với dataItemType: typeof BetterDataItem = BetterDataItem; công trình vì bạn thực hiện các trình biên dịch typescript để thêm lệnh JS: this.dataItemType = BetterDataItem; mà có thể được sử dụng sau này.

4

Lựa chọn 1: Bạn có thể ghi đè lên phương thức trong mỗi lớp phụ ...

export class BaseClass{ 
    dataItems:DataItem[]; 

    create() { 
     this.dataItems.push(new DataItem()); 
    } 
} 

export class BetterClass extends BaseClass{ 
    dataItems:BetterDataItem[]; 

    create() { 
     this.dataItems.push(new BetterDataItem()); 
    } 
} 

export class BestClass extends BaseClass{ 
    dataItems:BestDataItem[]; 

     create() { 
     this.dataItems.push(new BestDataItem()); 
    } 
} 

Phương án 2: Nhưng nếu bạn giới thiệu một lớp cơ sở chung, bạn có thể loại bỏ sự cần thiết phải xác định dataItems tài sản trên mỗi và cũng tạo ra các trường hợp khác nhau.

type MyT = typeof DataItem; 

export class GenericBaseClass<T extends DataItem> { 
    dataItems:T[]; 

    constructor(private dataType: MyT) { 

    } 

    create() { 
     this.dataItems.push(<T>new this.dataType()) 
    } 

} 

export class BaseClass extends GenericBaseClass<DataItem> { 
    constructor() { 
     super(DataItem); 
    } 
} 

export class BetterClass extends GenericBaseClass<DataItem> { 
    constructor() { 
     super(BetterDataItem); 
    } 
} 

export class BestClass extends GenericBaseClass<DataItem> { 
    constructor() { 
     super(BestDataItem); 
    } 
} 
+1

+1; Vì lợi ích của sự hoàn chỉnh, tôi nghĩ bạn có thể sử dụng toán tử 'instanceof' trong' BaseClass' nhưng nó thực sự là một anti-pattern trong trường hợp này. (http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf 4.13 Loại xác nhận) –

+0

Cảm ơn. Vì vậy, tôi giả định rằng không thể đơn giản nhận được một loại của một lớp từ một biến và sau đó tạo ra một lớp học?instanceof sẽ yêu cầu kiểm tra từng loại, vì vậy nó thực sự không phải là một giải pháp tốt. – zeroin

Các vấn đề liên quan