Bagaimana cara melewatkan parameter opsional sambil menghilangkan beberapa parameter opsional lainnya?

282

Diberikan tanda tangan berikut:

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

Bagaimana saya bisa memanggil fungsi error() tidak menentukan titleparameter, tetapi pengaturan autoHideAftermengatakan 1000?

g.pickardou
sumber

Jawaban:

307

Seperti yang ditentukan dalam dokumentasi , gunakan 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);

Tautan taman bermain .

Thomas
sumber
6
@ BBi7 Saya pikir Anda salah mengerti dokumentasi. Itu ?ditambahkan dalam definisi fungsi , tetapi pertanyaannya adalah tentang sebenarnya memanggil fungsi.
Thomas
Hai @ Thomas Saya benar-benar mengerti dokumentasinya dan tahu Anda harus menambahkannya? setelah parameter dalam definisi fungsi. Tapi, terkait dengan memanggil fungsi dengan parameter opsional, saya anggap lewat tidak terdefinisi jika tidak berlaku. Saya biasanya saya mencoba mencari cara untuk membuat parameter opsional (s) sebagai parameter akhir (s) jadi saya tidak bisa lulus vs tidak terdefinisi. Tetapi jelas jika Anda memiliki banyak maka Anda harus lulus tidak terdefinisi atau apa pun yang tidak benar. Saya tidak yakin apa yang saya maksud ketika saya memposting. Berarti saya tidak tahu apakah itu diedit tetapi apa yang saya lihat sekarang sudah benar.
BBi7
2
@ BBi7 Tidak ada suntingan terbaru. Oke, tidak apa-apa :) (Perhatikan bahwa Anda benar-benar harus lulus undefineduntuk mendapatkan perilaku yang sama seperti meninggalkan argumen sepenuhnya. Hanya "apa pun yang tidak benar" tidak akan berfungsi, karena TypeScript sebenarnya membandingkan void 0yang merupakan cara penulisan yang lebih aman undefined. )
Thomas
71

Sayangnya tidak ada yang seperti ini di TypeScript (lebih detail di sini: https://github.com/Microsoft/TypeScript/issues/467 )

Tetapi untuk menyiasatinya, Anda dapat mengubah params menjadi antarmuka:

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

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

//then to call it:
error({message: 'msg', autoHideAfter: 42});
Brocco
sumber
Bisakah Anda memberi tahu, bisakah saya memanggil metode kesalahan karena ini, error ({message: 'test'}), saya pikir, kami tidak bisa, jadi error ({message: 'test', autoHideAFter: undefined}), tetapi apa yang saya harapkan adalah kesalahan (pesan), Jika saya tidak lulus parameter lain, ia harus mengambil nilai dari parameter default.
Cegone
37

Anda dapat menggunakan variabel opsional dengan ?atau jika Anda memiliki beberapa variabel opsional ..., misalnya:

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

Di atas:

  • name diperlukan
  • country diperlukan dan memiliki nilai default
  • address adalah opsional
  • hobbies adalah array params opsional
Hasan A Yousef
sumber
2
Bukankah seharusnya hobi diketik sebagai array?
ProgrammerPer
4
Ada info yang berguna dalam jawaban ini, tetapi tidak menjawab pertanyaan. Pertanyaannya adalah, seperti yang saya lihat, bagaimana seseorang dapat mem-bypass / melewati beberapa parameter opsional dan hanya mengatur yang spesifik.
MaxB
2
negara tidak diperlukan, ini merupakan param opsional yang memiliki nilai default 'CA' alih-alih tidak ditentukan. jika diperlukan maka apa gunanya memberikan nilai default?
Anand Bhushan
19

Pendekatan lain adalah:

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

Jadi ketika Anda ingin menghilangkan parameter judul, cukup kirim data seperti itu:

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

Saya lebih suka opsi ini karena memungkinkan saya untuk menambahkan lebih banyak parameter tanpa harus mengirim yang lain.

Gabriel Castillo Prada
sumber
Bagaimana Anda akan meneruskan nilai default title?
Dan Dascalescu
13

Ini hampir sama dengan jawaban @Brocco, tetapi dengan sedikit twist: hanya memberikan parameter opsional pada objek. (Dan juga membuat objek params opsional).

Itu akhirnya menjadi seperti kwarg ** Python, tetapi tidak persis.

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:');
Monkpit
sumber
5

Anda dapat menentukan beberapa tanda tangan metode pada antarmuka kemudian memiliki beberapa metode kelebihan beban pada metode kelas:

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
    }
}

Sekarang semua ini akan berhasil:

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

... dan errormetode INotificationServiceakan memiliki opsi berikut:

Intellisense berlebihan

Tempat bermain

David Sherret
sumber
9
Hanya sebuah catatan yang saya akan merekomendasikan terhadap ini dan bukannya meneruskan objek dan meletakkan parameter ini sebagai properti pada objek itu ... itu jauh lebih sedikit bekerja dan kode akan lebih mudah dibaca.
David Sherret
2

Anda bisa membuat metode pembantu yang menerima basis parameter satu objek berdasarkan argumen kesalahan

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

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

Anda dapat mencoba mengatur judul menjadi nol.

Ini berhasil untuk saya.

error('This is the ',null,1000)
numpsi
sumber
3
Ini akan bekerja karena jika parameter fungsi memiliki nilai default ketika Anda mengirim nol ke parameter fungsi itu tidak akan ditetapkan ke nilai defaultnya
Okan SARICA
-2

Anda dapat melakukan ini tanpa antarmuka.

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

gunakan ?operator sebagai parameter opsional.

Rick
sumber
tetapi ini tidak memungkinkan Anda untuk menentukan messagedanautoHideAfter
Simon_Weaver
3
Anda tidak menjawab pertanyaan atau Anda tidak membacanya. Dia ingin tahu cara memanggil metode dengan beberapa parameter opsional, tanpa harus menentukan opsional pertama jika dia hanya ingin memasukkan yang kedua.
Gregfr