Làm thế nào để vượt qua các tham số tùy chọn trong khi bỏ qua một số tham số tùy chọn khác?


282

Cho chữ ký sau:

export interface INotificationService {
    error(message: string, title?: string, autoHideAfter?: number);
}

Làm thế nào tôi có thể gọi hàm error() không chỉ định titletham số, nhưng cài đặt autoHideAfterđể nói 1000?

Câu trả lời:


307

Theo quy định trong tài liệu , sử dụng undefined:

export interface INotificationService {
    error(message: string, title?: string, autoHideAfter? : number);
}

class X {
    error(message: string, title?: string, autoHideAfter?: number) {
        console.log(message, title, autoHideAfter);
    }
}

new X().error("hi there", undefined, 1000);

Liên kết sân chơi .


6
@ BBi7 Tôi nghĩ bạn đã hiểu nhầm tài liệu. Cái ?được thêm vào trong định nghĩa hàm , nhưng câu hỏi là về việc thực sự gọi hàm.
Thomas

Xin chào @Thomas Tôi hoàn toàn hiểu tài liệu và biết bạn phải thêm? sau tham số trong định nghĩa hàm. Nhưng, liên quan đến việc gọi một hàm với (các) tham số tùy chọn mà tôi cho là sẽ chuyển không xác định nếu không áp dụng. Nói chung, tôi cố gắng tìm cách tạo (các) tham số tùy chọn làm (các) tham số kết thúc để tôi không thể vượt qua so với không xác định. Nhưng rõ ràng nếu bạn có nhiều thì bạn cần phải vượt qua không xác định hoặc bất cứ điều gì không đúng sự thật. Tôi không chắc chắn những gì tôi đã đề cập trở lại khi tôi đăng lần đầu. Có nghĩa là tôi không biết nếu nó đã được chỉnh sửa nhưng những gì tôi thấy bây giờ là chính xác.
BBi7

2
@ BBi7 Không có chỉnh sửa gần đây. Được rồi, đừng bận tâm :) (Lưu ý rằng bạn thực sự phải vượt qua undefinedđể có được hành vi tương tự như loại bỏ hoàn toàn đối số. Chỉ là "bất cứ điều gì không đúng sự thật" sẽ không hoạt động, bởi vì TypeScript thực sự so sánh với void 0cách viết an toàn hơn undefined. )
Thomas

71

Thật không may, không có gì giống như vậy trong TypeScript (chi tiết hơn ở đây: https://github.com/Microsoft/TypeScript/issues/467 )

Nhưng để giải quyết vấn đề này, bạn có thể thay đổi thông số của mình thành giao diện:

export interface IErrorParams {
  message: string;
  title?: string;
  autoHideAfter?: number;
}

export interface INotificationService {
  error(params: IErrorParams);
}

//then to call it:
error({message: 'msg', autoHideAfter: 42});

Bạn có thể vui lòng cho tôi biết, tôi có thể gọi phương thức lỗi như thế này không, lỗi ({message: 'test'}), tôi nghĩ, chúng tôi không thể, vì vậy lỗi ({message: 'test', autoHideAFter: không xác định}), nhưng những gì tôi đang mong đợi là lỗi (tin nhắn), nếu tôi không vượt qua các thông số khác, nó sẽ lấy các giá trị từ các tham số mặc định.
Cegone

37

bạn có thể sử dụng biến tùy chọn theo ?hoặc nếu bạn có nhiều biến tùy chọn theo ..., ví dụ:

function details(name: string, country="CA", address?: string, ...hobbies: string) {
    // ...
}

Ở trên:

  • name bắt buộc
  • country là bắt buộc và có giá trị mặc định
  • address Là tùy chọn
  • hobbies là một mảng các thông số tùy chọn

2
Không nên sở thích được gõ như một mảng?
Lập trình viên

4
Có một thông tin hữu ích trong câu trả lời này, nhưng nó không trả lời câu hỏi. Câu hỏi là, như tôi thấy, làm thế nào người ta có thể bỏ qua / bỏ qua một vài tham số tùy chọn và chỉ đặt các tham số cụ thể.
MaxB

2
quốc gia không bắt buộc, đó là thông số tùy chọn có giá trị mặc định là 'CA' thay vì không xác định. nếu nó được yêu cầu thì điểm cung cấp giá trị mặc định là gì?
Anand Bhushan

19

Một cách tiếp cận khác là:

error(message: string, options?: {title?: string, autoHideAfter?: number});

Vì vậy, khi bạn muốn bỏ qua tham số tiêu đề, chỉ cần gửi dữ liệu như thế:

error('the message', { autoHideAfter: 1 })

Tôi muốn thay vì tùy chọn này vì cho phép tôi thêm nhiều tham số mà không phải gửi cho người khác.


Làm thế nào bạn cũng sẽ vượt qua một giá trị mặc định title?
Dan Dascalescu

13

Điều này gần giống như câu trả lời của @Brocco, nhưng với một thay đổi nhỏ: chỉ truyền các tham số tùy chọn trong một đối tượng. (Và cũng làm cho đối tượng params tùy chọn).

Nó cuối cùng giống như ** kwargs của Python, nhưng không chính xác.

export interface IErrorParams {
  title?: string;
  autoHideAfter?: number;
}

export interface INotificationService {
  // make params optional so you don't have to pass in an empty object
  // in the case that you don't want any extra params
  error(message: string, params?: IErrorParams);
}

// all of these will work as expected
error('A message with some params but not others:', {autoHideAfter: 42});
error('Another message with some params but not others:', {title: 'StackOverflow'});
error('A message with all params:', {title: 'StackOverflow', autoHideAfter: 42});
error('A message with all params, in a different order:', {autoHideAfter: 42, title: 'StackOverflow'});
error('A message with no params at all:');

5

Bạn có thể chỉ định nhiều chữ ký phương thức trên giao diện sau đó có quá tải nhiều phương thức trên phương thức lớp:

interface INotificationService {
    error(message: string, title?: string, autoHideAfter?: number);
    error(message: string, autoHideAfter: number);
}

class MyNotificationService implements INotificationService {
    error(message: string, title?: string, autoHideAfter?: number);
    error(message: string, autoHideAfter?: number);
    error(message: string, param1?: (string|number), param2?: number) {
        var autoHideAfter: number,
            title: string;

        // example of mapping the parameters
        if (param2 != null) {
            autoHideAfter = param2;
            title = <string> param1;
        }
        else if (param1 != null) {
            if (typeof param1 === "string") {
                title = param1;
            }
            else {
                autoHideAfter = param1;
            }
        }

        // use message, autoHideAfter, and title here
    }
}

Bây giờ tất cả những thứ này sẽ hoạt động:

var service: INotificationService = new MyNotificationService();
service.error("My message");
service.error("My message", 1000);
service.error("My message", "My title");
service.error("My message", "My title", 1000);

... và errorphương thức INotificationServicesẽ có các tùy chọn sau:

Quá tải

Sân chơi


9
Chỉ cần một lưu ý rằng tôi sẽ khuyên bạn nên chống lại điều này và thay vào đó truyền vào một đối tượng và đặt các tham số này làm các thuộc tính trên đối tượng đó ... nó sẽ hoạt động ít hơn rất nhiều và mã sẽ dễ đọc hơn.
David Sherret

2

Bạn có thể tạo một phương thức trợ giúp chấp nhận một tham số đối tượng dựa trên các đối số lỗi

 error(message: string, title?: string, autoHideAfter?: number){}

 getError(args: { message: string, title?: string, autoHideAfter?: number }) {
    return error(args.message, args.title, args.autoHideAfter);
 }

-1

Bạn có thể thử đặt tiêu đề thành null.

Điều này làm việc cho tôi.

error('This is the ',null,1000)

3
Woulndt này hoạt động vì nếu tham số chức năng có giá trị mặc định khi bạn gửi null đến tham số chức năng đó sẽ không được đặt thành giá trị mặc định
Okan SARICA

-2

Bạn có thể làm điều này mà không cần một giao diện.

class myClass{
  public error(message: string, title?: string, autoHideAfter? : number){
    //....
  }
}

sử dụng ?toán tử như một tham số tùy chọn.


nhưng điều này không cho phép bạn có bất kỳ cách nào để chỉ định messageautoHideAfter
Simon_Weaver

3
bạn không trả lời câu hỏi hoặc bạn đã không đọc nó. Anh ta muốn biết cách gọi một phương thức với nhiều tham số tùy chọn, mà không phải chỉ định tùy chọn đầu tiên nếu anh ta chỉ muốn nhập phương thức thứ hai.
Gregfr
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.