2013-09-16 103 views
9

Tôi đang cố gắng viết lại một số mã JavaScript của mình trong TypeScript. Một số mã này có tham chiếu đến một phần mở rộng mà tôi đã thêm vào nguyên mẫu đối tượng chuỗi.Mở rộng các loại cơ bản trong TypeScript, lỗi: "_không được xác định ..."

String.prototype.format = function() { 
    var formatted = this; 
    for (var i = 0; i < arguments.length; i++) { 
     formatted = formatted.replace(
      RegExp("\\{" + i + "\\}", 'g'), arguments[i].toString()); 
    } 
    return formatted; 
}; 

Tuy nhiên việc thêm tập lệnh kiểu này lại khá khó khăn.

Tôi đã xem các ví dụ nơi bạn khai báo một phần mở rộng của giao diện cơ bản sau đó gán một hàm cho mẫu thử nghiệm để khớp với giao diện và cung cấp chức năng của bạn. Giống như rất ...

interface String { 
    showString:() => string; 
} 

String.prototype.showString =(): string { 
    return this; 
}; 

Trừ lỗi này vì "_this không được định nghĩa ..."

Những điều khác tôi đã cố gắng là để tạo ra một lớp mới để mở rộng chuỗi ...

export class MoreString extends string { 

} 

Tuy nhiên điều này cũng không hoạt động vì bạn chỉ có thể mở rộng lớp và chuỗi/Chuỗi không phải là lớp học mà được xây dựng trong các loại.

Cách đơn giản nhất để mở rộng Chuỗi và truy cập vào phương pháp mở rộng của tôi là gì?

Trả lời

11

tôi đã kết thúc chạy vào một vấn đề khác sau này trong ngày hôm đó khiến tôi thấy chuyện gì đang xảy ra ở đây. Từ trên cùng, đây là ...

TypeScript được xây dựng trên đầu trang của JavaScript, vì vậy như @Nypan nói JavaScript là TypeScript hợp lệ. Bởi vì điều này, sự khác biệt rất dễ bỏ qua.

Một hàm JavaScript như thế này tham chiếu đến phạm vi mà hàm thực hiện bằng "this".

var f = function (postFix) {return this + postFix}; 

Để thêm cú pháp nguyên cảo bạn sẽ xác định loại

var f = function (postFix: string): string {return this + postFix}; 

Trong cả hai trường hợp này đề cập đến phạm vi chức năng giống như JavaScript cổ điển. Tuy nhiên, mọi thứ thay đổi khi chúng tôi thực hiện việc này ...

var f = (postFix: string): string {return this + postFix}; 
//or more correctly 
var f = (postFix: string): string => {return this + postFix}; 

Khi bạn xóa hàm từ trước các thông số thì nó không còn là chức năng cổ điển nữa. Nó trở thành một chức năng "Fat Arrow", rõ ràng ngay cả khi sử dụng cú pháp "=>". Trong các ví dụ trên "this" bây giờ đề cập đến lớp rằng hàm tồn tại giống như trong C#.

Trong nỗ lực gán một hàm cho nguyên mẫu chuỗi, tôi bỏ qua từ khóa hàm để nó được hiểu là hàm "Mũi tên chất béo" và cố gắng liên kết nó với phạm vi của lớp. Tuy nhiên, liều chức năng không tồn tại trong một lớp và gây ra lỗi "_this không được xác định".

Khi tôi thêm từ khóa "chức năng", hàm này được hiểu như tôi dự định và hoạt động chính xác.

interface String { 
    format:() => string; 
} 

String.prototype.format = function() : string { 
    var formatted = this; 
    for (var i = 0; i < arguments.length; i++) { 
     formatted = formatted.replace(
      RegExp("\\{" + i + "\\}", 'g'), arguments[i].toString()); 
    } 
    return formatted; 
}; 
2

Trong trường hợp chính xác tương tự tôi làm điều đó như thế:

interface String { 
    endsWith(str); 
    startsWith(str); 

} 

Đây chỉ là để đáp ứng các trình biên dịch. Bạn thực hiện các phương thức chính xác như trong javascript.

Hy vọng điều đó sẽ hữu ích.

2

Tôi nghĩ rằng đây là điều tương tự mà bước tiến đã nhận được tại nhưng bạn chỉ cần mở rộng nó trong javascript (javascript là hợp lệ typescript) và sau đó giao diện các chức năng mới.

dụ viết tắt:

String.prototype.myExtension = function() { 
    return this + " something." 
}; 

interface String { 
    myExtension :() => string; 
} 

alert("test".myExtension()); 
+1

Nhưng nơi ở mã bạn thêm định nghĩa này? bởi vì tôi nhận được thuộc tính 'myExtension' không tồn tại trên loại 'Chuỗi', vì vậy nó không được biên dịch. Tôi có đoạn mã bên trong định nghĩa mô-đun. – Oscar

+0

Điều này làm việc cho tôi, TANKS! – Benoit

+0

@Oscar cùng, không hoạt động trên mỏ –

1

Bạn cần phải mở rộng giao diện chuỗi như thế này:

interface String { 
    stringFormat(...args: string[]): string; 
} 

và bạn cần phải thực hiện như nguồn này

module Utilities { 
    String.prototype.stringFormat = function(): string { 
     var args = arguments; 
     return this.replace(/\{\{|\}\}|\{(\d+)\}/g, function (m, n) { 
      if (m == "{{") { return "{"; } 
      if (m == "}}") { return "}"; } 
      return args[n]; 
     }); 
    } 
} 

thực hiện: Equivalent of String.format in jQuery

+0

Tầm quan trọng của 'tiện ích mô-đun' ... CẢM ƠN BẠN! – mlorber