Rumah > Artikel > hujung hadapan web > Ts Lanjutan: Parameter bergantung, kesatuan yang disimpulkan dan interaksi yang sihat di Twitter.
Terdapat satu senario di mana perasaan ini sangat sengit: apabila fungsi mengambil parameter yang bergantung pada "mod" yang aktif.
lebih jelas dengan beberapa contoh kod:
type Provider = "PROVIDER A" | "PROVIDER B"; type ProviderAOpts = { ... }; type ProviderBOpts = { ... }; function connect(provider: Provider, options: ProviderAOpts | ProviderBOpts) { switch (provider) { case "PROVIDER A": // options is ProviderAOpts case "PROVIDER B": // options is ProviderBOpts } }
(Saya cuba menggunakan nama yang lebih realistik berbanding foo, goo, anjing dan kucing).
Jika anda telah meluangkan sedikit masa dengan TypeScript, anda mungkin mengesyaki kami pernah mengendalikan perkara ini sebagai ProviderAOpts, sebagai ProviderBOpts.
Tetapi ada masanya anda menghentak penumbuk anda di atas meja dan mendakwa: "Tiada lagi!"
Perkara pertama yang selalu terlintas di fikiran saya dalam kes ini ialah menggunakan fungsi lebih muatan:
function connect(provider: "PROVIDER A", options: ProviderAOpts): void; function connect(provider: "PROVIDER B", options: ProviderBOpts): void; function connect(provider: Provider, options: ProviderAOpts | ProviderBOpts) { switch (provider) { case "PROVIDER A": // (options as ProviderAOpts) ❌ case "PROVIDER B": // (options as ProviderBOpts) ❌ } }
Yang tidak berkesan. Tandatangan fungsi tidak disimpulkan dengan betul. Parameter pilihan sentiasa ProviderAOpts | ProviderBOpts. yang akan menyelesaikan kepada kesatuan bersama.
Ts tidak memautkan kedua-dua parameter dengan betul.
Alat seterusnya yang saya cuba ialah Jenis Predikat:
type ConnectOptions = ProviderAOpts | ProviderBOpts; function isAOptions(options: ConnectOptions): options is ProviderAOpts { return (options as ProviderAOpts).$$$ !== undefined; } function isBOptions(options: ConnectOptions): options is ProviderBOpts { return (options as ProviderBOpts).$$$ !== undefined; } function connect(provider: Provider, options: ConnectOptions) { switch (provider) { case "PROVIDER A": if (isAOptions(options)) { ... } case "PROVIDER B": if (isBOptions(options)) { ... } } ... }
Tetapi secara jujur, kami tidak menyelesaikan apa-apa. Kami baru sahaja memindahkan as di bawah permaidani ?. Memperkenalkan ifs tambahan dan, kami masih tidak memautkan parameter.
Generik. Saya cuba menggunakan generik untuk memautkan parameter. Tidak berfungsi:
function connect<T extends Provider>( provider: T, options: T extends "PROVIDER A" ? ProviderAOpts : ProviderBOpts ) { switch (provider) { case "PROVIDER A": // (options as ProviderAOpts) ❌ case "PROVIDER B": // (options as ProviderBOpts) ❌ } }
Saya cuba bersungguh-sungguh dan berjaya setakat ini
Tapi akhirnya tak kisah pun
Saya terpaksa jatuh untuk kehilangan semuanya
Tapi akhirnya tak kisah pun
?
Mengubah suai parameter opts menambahkan jenis pembekal melakukan silap mata:
type Provider = "PROVIDER A" | "PROVIDER B"; type ProviderOptsBase = { provider: Provider; } type ProviderAOpts = ProviderOptsBase & { provider: "PROVIDER A"; ...; }; type ProviderBOpts = ProviderOptsBase & { provider: "PROVIDER B"; ...; }; function connect(options: ConnectOptions) { switch (options.provider) { case "PROVIDER A": // options is ProviderAOpts ✅ case "PROVIDER B": // options is ProviderBOpts ✅ } }
Ini adalah penyelesaian yang paling biasa, tetapi tidak selalu boleh menukar tandatangan fungsi. Atau mungkin anda tidak mahu. Soal prinsip ?.
Terima kasih kepada Mateusz Burzyński (@AndaristRake) dan Lenz Weber (@phry)
type Provider = "PROVIDER A" | "PROVIDER B"; type ProviderAOpts = { ... }; type ProviderBOpts = { ... }; function connect( ...[provider, options]: | ["PROVIDER A", ProviderAOpts] | ["PROVIDER B", ProviderBOpts] ) { switch (provider) { case "PROVIDER A": // options is ProviderAOpts ✅ case "PROVIDER B": // options is ProviderBOpts ✅ ... } }5. Apa yang berfungsi: tupel yang dimusnahkan
connect("PROVIDER A", { ... }); connect("PROVIDER B", { ... }); ^ autocomplete works ✅
Jadi perkaranya ialah kami sedang memusnahkan tuple (array) dengan jenis yang tepat yang kami mahukan.
type Provider = "PROVIDER A" | "PROVIDER B"; type ProviderAOpts = { ... }; type ProviderBOpts = { ... }; type ProviderOpts = { "PROVIDER A": ProviderAOpts; "PROVIDER B": ProviderBOpts; }; // solves to // ["PROVIDER A", ProviderAOpts] | ["PROVIDER B", ProviderBOpts] type ConnectOptions = { [K in keyof ProviderOpts]: [K, ProviderOpts[K]]; }[keyof ProviderOpts]; function connect(...[provider, options]: ConnectOptions) { switch (provider) { case "PROVIDER A": // options is ProviderAOpts ✅ case "PROVIDER B": // options is ProviderBOpts ✅ ... } }6. Apakah yang berfungsi: penyelesaian tuple umum
connect("PROVIDER A", { ... }); connect("PROVIDER B", { ... }); ^ autocomplete works ✅
type Provider = "PROVIDER A" | "PROVIDER B"; type ProviderAOpts = { ... }; type ProviderBOpts = { ... }; type ProviderOpts = { "PROVIDER A": ProviderAOpts; "PROVIDER B": ProviderBOpts; }; // aux type to extract the key and the options from ProviderOpts type KeyOpts<T> = { [K in keyof T]: [K, T[K]]; }[keyof T]; function connect(...[provider, options]: KeyOpts<ProviderOpts>) { switch (provider) { case "PROVIDER A": // options is ProviderAOpts ✅ case "PROVIDER B": // options is ProviderBOpts ✅ ... } }7. TL;DR. COPY PASTE, TERIMA KASIH
connect("PROVIDER A", { ... }); connect("PROVIDER B", { ... }); ^ autocomplete works ✅
Terima kasih kepada Mateusz dan Lenz atas bantuan ?.
terima kasih kerana membaca ?. <script> // Detect dark theme var iframe = document.getElementById('tweet-1840828253684056557-683'); if (document.body.className.includes('dark-theme')) { iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1840828253684056557&theme=dark" } </script> <script> // Detect dark theme var iframe = document.getElementById('tweet-1840346445334864141-950'); if (document.body.className.includes('dark-theme')) { iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1840346445334864141&theme=dark" } </script>Atas ialah kandungan terperinci Ts Lanjutan: Parameter bergantung, kesatuan yang disimpulkan dan interaksi yang sihat di Twitter.. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!