Typescript: Mendukung operator pipa ES Berikutnya "|>" yang diusulkan

Dibuat pada 10 Agu 2017  ·  79Komentar  ·  Sumber: microsoft/TypeScript

ES Next Suggestion Waiting for TC39

Komentar yang paling membantu

Sekarang sudah tahap 1

Semua 79 komentar

Proposal favorit saya :( Saat ini, kami benar-benar dapat menulis program gratis this .

Untuk referensi, proposal TC39: https://github.com/tc39/proposal-pipeline-operator

Bukan berarti proposalnya belum sampai tahap 0. Jika pernah ditambahkan ke semantik bahasa dan detail lainnya kemungkinan akan berubah.

Ini akan menjadi yang pertama saya pikir (selain beberapa oldies seperti Enum dan sistem modul) tetapi dapatkah TypeScript mengimplementasikan ini memberikannya lebih banyak visibilitas dan meningkatkan permintaan untuknya di ekosistem ecma lainnya?

Hanya ingin berbagi solusi untuk operator pipa yang hilang yang terinspirasi oleh https://vanslaars.io/post/create-pipe-function/...

SyncPipe dengan reduksi sinkron

// SyncPipe with synchronous reduction
type SyncPipeMapper<T, U> = (data: T | U) => U;
type SyncPipeReducer<T, U> = (f: SyncPipeMapper<T, U>, g: SyncPipeMapper<T, U>) => SyncPipeMapper<T, U>;
type SyncPipe<T, U> = (...fns: SyncPipeMapper<T, U>[]) => SyncPipeMapper<T, U>;
function createSyncPipe<T, U>(): SyncPipe<T, U> {
    const syncPipe: SyncPipeReducer<T, U> = (f: SyncPipeMapper<T, U>, g: SyncPipeMapper<T, U>) => (data: T) => g(f(data));
    return (...fns: SyncPipeMapper<T, U>[]): SyncPipeMapper<T, U> => fns.reduce(syncPipe);
}

// Example:
function testSyncPipe(num: number): number {
    const addOne: SyncPipeMapper<number, number> = (data: number): number => {
        return data + 1;
    }
    const syncPipe: SyncPipe<number, number> = createSyncPipe();
    const syncWaterfall: SyncPipeMapper<number, number> = syncPipe(
        addOne,
        addOne,
        addOne,
    );

    // Does the equivalent of num+3
    const lastnumber: number = syncWaterfall(num);
    return lastnumber;
}

AsyncPipe dengan reduksi asinkron

// AsyncPipe with asynchronous reduction
type AsyncPipeMapper<T, U> = (data: T | U) => Promise<U>;
type AsyncPipeReducer<T, U> = (f: AsyncPipeMapper<T, U>, g: AsyncPipeMapper<T, U>) => AsyncPipeMapper<T, U>;
type AsyncPipe<T, U> = (...fns: AsyncPipeMapper<T, U>[]) => AsyncPipeMapper<T, U>;
function createAsyncPipe<T, U>(): AsyncPipe<T, U> {
    const asyncPipe: AsyncPipeReducer<T, U> = (f: AsyncPipeMapper<T, U>, g: AsyncPipeMapper<T, U>) => async (data: T) => g(await f(data));
    return (...fns: AsyncPipeMapper<T, U>[]): AsyncPipeMapper<T, U> => fns.reduce(asyncPipe);
}

// Example:
async function testAsyncPipe(num: number): Promise<number> {
    const addOne: AsyncPipeMapper<number, number> = async (data: number): Promise<number> => {
        return data + 1;
    }
    const asyncPipe: AsyncPipe<number, number> = createAsyncPipe();
    const asyncWaterfall: AsyncPipeMapper<number, number> = asyncPipe(
        addOne,
        addOne,
        addOne,
    );

    // Does the equivalent of num+3
    const lastnumber: number = await asyncWaterfall(num);
    return lastnumber;
}

Pipa dengan reduksi asinkron (disederhanakan)

Saya paling sering menggunakan yang ini:

// Pipes with asynchronous reduction
type PipeMapper<T> = (data: T) => Promise<T>;
type PipeReducer<T> = (f: PipeMapper<T>, g: PipeMapper<T>) => PipeMapper<T>;
type Pipe<T> = (...fns: PipeMapper<T>[]) => PipeMapper<T>;
function createPipe<T>(): Pipe<T> {
    const pipePipe: PipeReducer<T> = (f: PipeMapper<T>, g: PipeMapper<T>) => async (data: T) => g(await f(data));
    return (...fns: PipeMapper<T>[]): PipeMapper<T> => fns.reduce(pipePipe);
}

// Example:
async function testPipe(num: number): Promise<number> {
    const addOne: PipeMapper<number> = async (data: number): Promise<number> => {
        return data + 1;
    }
    const pipe: Pipe<number> = createPipe();
    const waterfall: PipeMapper<number> = pipe(
        addOne,
        addOne,
        addOne,
    );
    // Does the equivalent of num+3
    const lastnumber: number = await waterfall(num);
    return lastnumber;
}

Saya harap Anda akan menemukan ini bermanfaat!

@PublicParadise terlalu banyak boilerplate :p

Sementara saya pasti ingin melihat beberapa varian dari operator ini dalam bahasa, kebutuhan yang dirasakan untuk itu berasal dari dua batasan berbeda dari ECMAScript seperti yang ada saat ini.

Yang pertama sangat sulit untuk diatasi atau bahkan diatasi dalam bahasa: ketidakmampuan untuk memperluas objek bawaan dengan cara yang higienis.

Namun yang kedua tidak memerlukan dukungan tingkat bahasa sama sekali dan sebenarnya dapat diperbaiki: perpustakaan standar dapat disebut anemia.

Maksimal Minimal adalah kegagalan total.

Mengapa perlu berbulan-bulan argumen untuk mendapatkan Array.prototype.flatMap dalam bahasa tersebut?

Itu salah satu metode dan seharusnya sudah ada sejak awal dan harus jelas bahwa itu harus ditambahkan.

Mungkin Array.prototype akan memiliki metode groupBy dalam 6 tahun.

Sekarang ini memiliki beberapa implementasi babel, yang diharapkan akan membantu sepanjang proposal TC39:

Sekarang sudah tahap 1

Jadi, ada kemungkinan si cantik ini masuk TS? Itu akan sejalan dengan F#. <3

Meskipun ada pengecualian, ketika proposal _penting_ untuk TypeScript dan jenisnya, proposal biasanya tidak diterapkan hingga mencapai TC39 Tahap 3 di TypeScript, karena tidak cukup stabil untuk memastikan bahwa tidak akan ada kerusakan dan regresi yang signifikan.

Meskipun belum ada tim inti yang mengomentari masalah ini, menurut saya itu tidak _penting_ cukup untuk dipertimbangkan untuk diterapkan sebelum Tahap 3. Fokus terbaik adalah mendukung sang juara dan proposal di TC39.

Andai saja TS memiliki opsi untuk hanya menyalurkan operator ini untuk mengizinkan babel dengan plugin untuk menanganinya.
Atau punya plugin sintaks sendiri, seperti yang dilakukan post-css. Beberapa tahun menunggu operator primitif terlalu banyak.

@garkin : Tantangannya di sini adalah TS perlu memahami kode untuk melakukan tugasnya menyediakan keamanan tipe, yang tidak digabungkan dengan baik dengan kode acak yang tidak dipahami. Kecuali untuk mendapatkan makro (#4892), dalam hal ini ia hanya akan dikompilasi ke kode yang dipahaminya. Tapi saya tidak akan berharap itu di peta jalan, karena beberapa bit dari perpustakaan standar masih menantang untuk mengetik atm.

Sekarang Babel memahami TypeScript, Anda dapat menjalankannya melalui Babel kemudian
naskah

Pada 26 Oktober 2017 19:01, "Tycho Grouwstra" [email protected] menulis:

@garkin https://github.com/garkin : Tantangannya di sini adalah TS perlu
memahami kode untuk melakukan tugasnya menyediakan keamanan tipe, yang tidak
menggabungkan dengan baik dengan kode acak itu tidak mengerti. Kecuali untuk mendapatkan
makro (#4892 https://github.com/Microsoft/TypeScript/issues/4892 ), di
kasus mana yang baru saja dikompilasi ke kode yang dipahaminya. Tapi saya tidak mau
berharap itu di peta jalan, karena beberapa standar
perpustakaan masih menantang untuk mengetik atm.


Anda menerima ini karena Anda yang menulis utas.
Balas email ini secara langsung, lihat di GitHub
https://github.com/Microsoft/TypeScript/issues/17718#issuecomment-339748284 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AAZQTO6UiVHbrM6SRwaBhm8obaa3R7e9ks5swMkCgaJpZM4OzVEg
.

Sekarang Babel memahami TypeScript, Anda dapat menjalankannya melalui Babel kemudian
naskah

Dua kali waktu pembuatannya :p

Akan lebih baik jika TypeScript hanyalah plugin Babel maka Anda tidak perlu
pipa melalui kedua program

Pada 26 Oktober 2017 20:16, "AlexGalays" [email protected] menulis:

Sekarang Babel memahami TypeScript, Anda dapat menjalankannya melalui Babel kemudian
naskah

Dua kali waktu pembuatannya :p


Anda menerima ini karena Anda yang menulis utas.
Balas email ini secara langsung, lihat di GitHub
https://github.com/Microsoft/TypeScript/issues/17718#issuecomment-339769856 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AAZQTEArBw8jj0BcZFM2yLj5ErfbtNrgks5swNqagaJpZM4OzVEg
.

@graingert : Ini adalah opsi yang bagus untuk dimiliki, saya akan menyelidiki ini.
Sayangnya, itu tidak akan bekerja dengan TypeScript Language Service API yang digunakan oleh VisualStudioCode, Webstorm dan IDE lainnya.

Mengenai "plugin TS" seseorang dapat dengan mudah mencapai hasil yang diinginkan dengan, katakanlah, transpiler (pra) sederhana untuk operator pipa yang memahami sintaks TS dan menghasilkan pernyataan yang diketik dengan kuat. Itu akan dikompilasi dengan baik dengan pemeriksaan tipe dan yang lainnya.

Konfigurasi webpack untuk itu bisa terlihat seperti ini:

module: {
        rules: [
            { test: /\.ts$/, loader: 'ts-pipe-operator', enforce: 'pre' },
            { test: /\.ts$/, loader: 'ts-loader' },
            ...
        ]
 }

Satu-satunya tantangan, seperti yang ditunjukkan oleh @garkin , adalah bahwa layanan TS tidak akan dapat mengkorelasikan bagian yang ditranspilasikan ke file sumber asli, maka IDE yang menggunakan layanan tersebut tidak akan berfungsi dengan baik meskipun mereka sudah mengenali operatornya (ES Next sintaks diaktifkan atau sesuatu).

Mungkin jika kita membuat NFR (atau mungkin sudah ada?) untuk layanan TS untuk mendukung peta sumber kumulatif yang akan diterapkan antara file sumber dan hasil transpilasi yang diumpankan ke kompiler, plugin ini dan plugin lainnya akan dimungkinkan tanpa mempengaruhi seluruh komunitas dan, yang paling penting, tanpa menambahkan lebih banyak kerumitan untuk ditangani oleh tim inti.


Juga, saya tidak tahu seberapa #13940 terkait dengan ini, tetapi tampaknya ini adalah awal yang baik untuk plugin yang lebih kompleks. Namun menurut saya pendekatan peta sumber masih merupakan alternatif yang jauh lebih sederhana karena transpiler minimalis (pra) tidak memerlukan konteks proyek untuk sebagian besar kasus karena akan cukup mudah untuk mengekstrak blok notasi tipe (jika ada) dari pernyataan teks mentah dan kemudian menulis ulang sedemikian rupa sehingga aliran kontrol akan dapat menyiratkan jenis I/O spesifik untuk bagian yang ditranskripsikan.


Last but not least, adakah yang bisa menunjukkan saya ke utas _official_ (jika ada) mengenai plugin semacam ini?

Saya harus mengatakan bahwa saya sangat menghargai cara yang tenang untuk memperkenalkan proposal baru dan lebih memilih TypeScript monolitik dan alat LessCSS lebih banyak daripada olimpiade plugin khusus Flow+Babel dan Post-CSS.

Ini adalah penyesuaian dan kecepatan mendapatkan fitur baru dengan biaya fragmentasi kembung dan bidang keahlian.

Operator pipa seperti obat masuk ke dunia fungsional, itu membuat saya mengatakan dan berharap hal-hal aneh.

Jadi, sudah ada #14419 dan bahkan beberapa implikasi praktis yang berguna. Seharusnya tidak sulit untuk mengintegrasikannya dengan ts-loader .

tsconfig.json transformers integration (dan juga Language Service API, tidak hanya disesuaikan tsc ) #14654 ditolak _dalam jangka pendek_.

11976 sedang membahas plugin Layanan Bahasa, yang terlihat seperti alat linting saja.

16607 mengusulkan perpanjangan plugin tersebut ke transformer.

@PublicParadise atau cukup gunakan flow lodash atau pipe dari Rambda?

lagi pula, ini akan sangat luar biasa untuk didukung di TS. Saya suka pola fungsional yang didukung JS (terutama dengan inferensi tipe TS), tetapi beberapa pola tidak terbaca dengan baik. Ini akan sangat besar karena perpustakaan TS besar seperti RxJS dan IxJS bergerak menuju komposisi fungsional tanpa titik melalui ekstensi/warisan prototipe, itu membuat pengocokan pohon yang jauh lebih baik dan dukungan untuk operator khusus.

@felixfbecker Maksudmu pipe ramda ? Saya perlu mencoba lagi tetapi secara historis, ramda menjadi lib pertama JS, sangat dinamis dan sulit untuk mengetik (seperti lodash), ditambah dengan fakta bahwa TS dulu memiliki banyak masalah dalam menyimpulkan dari nilai pengembalian fungsi (mungkin diperbaiki baru-baru ini, tetapi tidak yakin)
Saya tidak menggunakan lodash karena dirancang dengan buruk, mencampur fungsi yang dapat berubah dan tidak dapat diubah dalam satu ruang nama besar.

Ini benar-benar berfungsi dengan baik jika fungsi dan rantai Anda tidak super gila:

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/b67c928904f03d0911c99ab938b14bc2e59cad40/types/lodash/index.d.ts#L7819 -L7855

Ini benar-benar berfungsi dengan baik jika fungsi dan rantai Anda tidak super gila

Biarkan saya memenuhi syarat 'tidak super gila' di sana: semuanya rusak jika fungsi Anda memiliki obat generik (lihat https://github.com/types/npm-ramda/issues/86), misalnya R.pipe(R.identity) .

Juga, mari kita perjelas, proposalnya adalah Tahap 1. Tim inti semakin malu untuk memperkenalkan hal-hal sebelum Tahap 3. Dekorator adalah bagian dari contoh. Meskipun mereka ditandai sebagai _experimental_, kami semua melanjutkan dan mengaktifkan flag itu dan menulis semua kode produksi kami menggunakan mereka. Proposal sekarang telah terpental dan ada beberapa perubahan mendasar dalam sintaks dan semantik yang berarti kita semua harus memperbaiki kode kita yang menempatkan tim inti dalam situasi yang ketat, karena jika mereka _hanya_ mendukung final sintaks daripada semua orang rusak pada hari mereka merilisnya, atau jika mereka menyimpan barang-barang warisan, perubahan lain dalam kompiler dapat membuatnya sulit untuk mendukung dua sintaks, dan akhirnya Anda ingin menyingkirkan barang-barang lama, tetapi ketika.. .

Jadi hal terbaik untuk dilakukan dengan fitur berbasis standar seperti ini, bukan untuk memperdebatkan dukungan TypeScript atau kurangnya dukungan di sini, ini adalah menemukan perwakilan TC39 lokal yang ramah dan menganjurkan bahwa fitur ini sangat penting bagi Anda serta berpartisipasi dalam percakapan proposal yang ditautkan ke atas di GitHub. Semakin cepat semantik diselesaikan dan semakin cepat mencapai Tahap 3, semakin cepat kita semua dapat memiliki hal-hal baik!

Sekarang rxjs memiliki operator yang dapat dibiarkan, ini akan menjadi fitur yang lebih mengagumkan untuk dimiliki di TypeScript
https://github.com/ReactiveX/rxjs/blob/master/doc/lettable-operators.md

Bisakah kami meminta seseorang dari tim TS untuk menjelaskan permintaan ini?

Mereka telah, mereka telah menandainya ES Next dan Suggestion ... Saya dapat mengutip Anda bab dan ayat lokasi lain di mana mereka telah mengomentari proposal ES Berikutnya dan kapan dan bagaimana mereka mengimplementasikannya...

Komentar dari mereka tidak akan mengubah apa pun. Apakah Anda pikir mereka diam-diam mengerjakannya di belakang layar, menunggu untuk menyebarkannya ke komunitas? Mereka sering tidak akan memasukkan masalah jika tidak ada yang ditambahkan... Tidak ada yang perlu ditambahkan pada apa yang telah dikatakan.

Pada titik ini saya percaya akan sangat berguna untuk memiliki plugin yang memperluas bahasa. Tambahkan fitur yang mereka tidak akan menjadi bagian dari inti bahasa akan menjadi bagian dari plugin ini.

@aminpaks Saya tidak terlalu menyukai ide itu karena dapat dengan cepat mengarah pada babelifikasi (seperti di Menara Babel bukan Babeljs transpiler yang sangat baik )

Karena plugin akan menyiratkan perilaku level tipe, menjadi sulit untuk memahami arti program dan menangani dependensi level sumber akan memerlukan sejumlah fitur kompleks tetapi sangat berguna yang saat ini kurang dimiliki oleh TypeScript.

Sebisa mungkin saya _suka_ ini ada di mana-mana, saya senang TS mengambil pendekatan yang lebih tertutup untuk mengimplementasikan fitur baru dan tetap berpegang pada standar. Sikap ini membuat TS lebih menarik secara keseluruhan bagi orang-orang seperti saya yang sangat peduli dengan penyimpangan dari standar tetapi menikmati fitur-fitur canggih yang disediakan transpilasi sebelum adopsi vendor browser / mesin JS (tetapi tidak harus mendahului standardisasi). Ini adalah tindakan penyeimbangan yang rumit.

Secara pribadi, saya tidak mendukung operator pipa dengan mengorbankan operator pengikat. Itu benar-benar turun ke keterbacaan.

Diberikan:

function* where<T>(items: Iterable<T>, predicate: (item:T)=>boolean){
  for (let item of items){
    if(predicate(item)) yield item;
  }
}

pengikatan:

[1,2,3]::where(x=>x>2)

operasi pipa:

[1,2,3]|>(_)=>where(_,x=>x>2)

ts-team benar dalam tidak mengganggu sampai tahap-3; itupun proposal tahap 3 masih bisa ditarik kembali (misal SIMD). Sayang sekali kami tidak dapat memiliki plugin - "risiko" diteruskan ke pengembang individu. Ada banyak kasus penggunaan lain untuk plugin juga, paling tidak untuk mendukung hal-hal seperti file .vue berisi TypeScript.

@MeirionHughes saya setuju. Sementara saya lebih suka memiliki operator pipa, daripada tanpa gula sama sekali, ini terinspirasi oleh bahasa di mana fungsi dibuat secara otomatis dan di mana perpustakaan dibangun dengan memanfaatkan itu. Ini juga mengasumsikan metode pipa adalah _not_ anggota dari nilai pipa.

Maka Anda akan memiliki

function where<T>(predicate: (item: T) => boolean): (items: Itererable<T>) => Itererable<T> {
  return function* () {
    for (const item of items) if (predicate(item)) yield item;
  };
}

function select<T, R>(projection: (item: T) => R): (items: Itererable<T>) => Itererable<R> {
  return function* () {
    for (const item of items) yield projection(item);
  };
}

dan kemudian Anda akan menulis

[1, 2, 3] |> where(x => x > 2) |> select(x => x ** 2);

tetapi karena JavaScript tidak dan tidak dapat melakukan fungsi kari otomatis, tampaknya hanya berfungsi dengan baik dengan pustaka yang dirancang dengan mempertimbangkan kari.

Saya mungkin salah tentang ini, saya tidak terlalu paham dengan proposal.

Kemudian perpustakaan baru yang menyediakan fungsi util kari secara default mungkin menjadi standar baru :p

@AlexGalays Saya pikir itu mungkin jika ini berlalu. Selama itu bukan bagian dari plot subversif untuk mengubah JavaScript menjadi OCaml, maka semuanya baik-baik saja.

@MeirionHughes contoh Anda tidak benar. Fungsi where Anda tidak menggunakan this sama sekali, jadi operator bind tidak akan berfungsi. Operator bind juga memiliki banyak pertanyaan terbuka untuk keamanan tipe. Apakah where diizinkan untuk mengakses properti pribadi dari this seperti metode kelas? Jika tidak, apa gunanya menggunakan this ? Jika ya, maka mengubah properti pribadi tiba-tiba merupakan perubahan yang menghancurkan, yang sepenuhnya mengalahkan tujuan properti pribadi.
Anda juga menyatakan bahwa sintaksnya kurang dapat dibaca, tetapi misalnya hilangkan parens dalam contoh operator-bind Anda tetapi tambahkan parens yang tidak dibutuhkan dalam contoh pipa. Dan operator pipa tentu saja tidak akan bekerja sama sekali dengan fungsi yang ditulis untuk mengikat, tetapi akan bekerja dengan baik untuk fungsi kari, seperti operator rxjs, ramda atau lodash/fp.

@aluanhaddad Selain semua pustaka fp, RxJS adalah contoh pustaka yang banyak digunakan yang berpindah dari operator pada prototipe (yang memiliki banyak masalah, sebagian besar seputar pengocokan pohon dan keamanan tipe generik) ke operator sebagai fungsi kari. Sebagian besar perpustakaan mungkin tidak memilih cara itu sekarang _karena_ kami tidak memiliki sintaks yang baik untuk itu.

@felixfbecker Anda benar dan contoh @aluanhaddad yang menyarangkan fungsi yang dihasilkan yang disalurkan telah mengubah pikiran saya sepenuhnya.

Adakah yang pernah memikirkan atau sedang menerapkan trafo khusus untuk mendapatkan dukungan pipa sedikit lebih awal? Dari kelihatannya itu bisa dilakukan melalui transformator kustom yang hanya memiliki babel transpile _just_ bagian pipa itu sendiri. Anda kemudian dapat menjalankannya melalui: https://github.com/cevek/ttypescript

Apakah itu sebuah kemungkinan? Menggunakan transformasi khusus untuk menggunakan sintaks yang didukung Babel, sambil menjaga hal-hal seperti perkakas TypeScripts berfungsi?

Mungkin? ada preset yang hanya berhubungan dengan proposal 0-2: https://www.npmjs.com/package/babel-preset-proposal-typescript - ini menyiratkan Anda memasukkan ini sebelum mengirimnya ke TypeScript. Anda intellisense kemungkinan akan borked sekalipun. Namun, dengan https://github.com/cevek/ttypescript#visual -studio-code Anda mungkin lolos begitu saja.

@MeirionHughes Saya senang itu membantu ❤️.
Sekarang kita hanya perlu #6606 sehingga kita dapat mengubah metode prototipe arbitrer menjadi fungsi kari!

TypeScript adalah transformasi babel sekarang, saya pikir harus ada cara untuk mengurutkan dalam pipa desugaring sebelum TypeScript lulus. Saya tidak tahu bagaimana Anda membuatnya berfungsi dengan server bahasa.

Saya menambahkan implementasi yang dihosting sendiri untuk TS #22816

Sebagai salah satu orang yang mendorong operator saluran pipa, saya mohon: Tolong _not_ terapkan ini di TypeScript hingga lebih lanjut. Kami masih memperdebatkan dua proposal potensial, yang pada dasarnya tidak kompatibel satu sama lain, jadi TypeScript memohon kepada dunia untuk menyusahkan jika mengimplementasikan ini terlalu dini.

Jika Anda tertarik dengan proposal ini, lihat repo di sini dan terlibatlah: https://github.com/tc39/proposal-pipeline-operator/ Kami akan senang menerima tanggapan Anda! Dan kami sedang mengerjakan plugin Babel untuk proposal yang berbeda, jadi Anda akan memiliki kesempatan untuk mencobanya di proyek (non-TypeScript) Anda.

Tetapi proposal tersebut belum siap untuk mendarat di sesuatu seperti TypeScript.

Kami jelas tidak menggabungkan ini.

Bisakah kita memiliki sesuatu seperti https://github.com/babel/babel-eslint , yang memungkinkan kita untuk terus menggunakan fitur yang didukung oleh Babel, dan membuat pemeriksaan tipe berfungsi setelah fitur yang tidak didukung oleh TypeScript dihilangkan?

@masaeedu Ya! Ini

@MeirionHughes dengan proposal aplikasi parsial menjadi lebih mudah:

[1,2,3] |> where(?, x=>x>2)

@bernatmv : dekat dengannya yang berfungsi hari ini.

@tycho01 Tapi tidak di TypeScript, tidak sampai mendapat 2.8 pengetikan: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/25067

@jeremejevs @bernatmv sebenarnya, R.__ telah diketik menggunakan codegen di npm-ramda . Cara yang lebih baik menggunakan 2.8 selamat datang!

Saya agak baru dalam Javascript dan TypeScript (2 minggu) jadi mohon maafkan saya jika ada solusi yang lebih sederhana di luar sana. Tetapi di bawah ini adalah apa yang saya temukan tanpa adanya operator pipa. Saya awalnya mencoba memiliki beberapa kelebihan pipe yang berfungsi dengan parameter tipe 2, 3, 4, dll., tetapi tidak dapat menemukan cara agar resolusi kelebihan TypeScript berfungsi seperti di C#. Kami dapat memiliki fungsi yang berbeda pipe1<A,B> , pipe2<A,B,C> , dan pipe3<A,B,C,D> tetapi ini akan sulit untuk dikerjakan karena Anda harus memilih nama fungsi berdasarkan berapa banyak argumen yang Anda ingin. Apakah ada solusi tipe-aman yang lebih sederhana daripada yang saya usulkan di bawah ini? Apakah ada definisi tipe rekursif yang dapat menerima jumlah parameter yang tidak terbatas? Apakah saya menggunakan tipe kondisi dengan benar?

type LastOf<
    A,
    B=never,
    C=never,
    D=never,
    E=never,
    F=never,
    G=never,
    H=never,
    I=never,
    J=never> =
    [B] extends [never] ? A :
    [C] extends [never] ? B :
    [D] extends [never] ? C :
    [E] extends [never] ? D :
    [F] extends [never] ? E :
    [G] extends [never] ? F :
    [H] extends [never] ? G :
    [I] extends [never] ? H :
    [J] extends [never] ? I :
    J;

export function pipe<A, B, C=never, D=never, E=never, F=never, G=never, H=never, I=never, J=never>(
    a: A,
    mapA: (a: A) => B,
    mapB?: (b: B) => C,
    mapC?: (c: C) => D,
    mapD?: (d: D) => E,
    mapE?: (e: E) => F,
    mapF?: (f: F) => G,
    mapG?: (g: G) => H,
    mapH?: (h: H) => I,
    mapI?: (i: I) => J
): LastOf<A, B, C, D, E, F, G, H, I, J> {
    if (mapB === undefined) {
        return mapA(a) as LastOf<A, B, C, D, E, F, G, H, I, J>;
    }
    if (mapC === undefined) {
        return mapB(mapA(a)) as LastOf<A, B, C, D, E, F, G, H, I, J>;
    }
    if (mapD === undefined) {
        return mapC(mapB(mapA(a))) as LastOf<A, B, C, D, E, F, G, H, I, J>;
    }
    if (mapE === undefined) {
        return mapD(mapC(mapB(mapA(a)))) as LastOf<A, B, C, D, E, F, G, H, I, J>;
    }
    if (mapF === undefined) {
        return mapE(mapD(mapC(mapB(mapA(a))))) as LastOf<A, B, C, D, E, F, G, H, I, J>;
    }
    if (mapG === undefined) {
        return mapF(mapE(mapD(mapC(mapB(mapA(a)))))) as LastOf<A, B, C, D, E, F, G, H, I, J>;
    }
    if (mapH === undefined) {
        return mapG(mapF(mapE(mapD(mapC(mapB(mapA(a))))))) as LastOf<A, B, C, D, E, F, G, H, I, J>;
    }
    if (mapI === undefined) {
        return mapH(mapG(mapF(mapE(mapD(mapC(mapB(mapA(a)))))))) as LastOf<A, B, C, D, E, F, G, H, I, J>;
    }
    return mapI(mapH(mapG(mapF(mapE(mapD(mapC(mapB(mapA(a))))))))) as LastOf<A, B, C, D, E, F, G, H, I, J>;
}

test("map once", () => {
    const result = pipe(
        2,
        i => i * 10);
    expect(result).toBe(20);
});

test("map twice", () => {
    const result = pipe(
        2,
        i => i * 10,
        i => `the answer is ${i}`);
    expect(result).toBe('the answer is 20');
});

test("map three times", () => {
    const result = pipe(
        2,
        i => i * 10,
        i => -i,
        i => ({ a: i, b: -i }));
    expect(result).toEqual({ a: -20, b: 20 });
});

Saya pikir _.flow lodash/fp sudah mengetik ini?

Pada Rabu, 9 Mei 2018, 22:19 jmagaram, [email protected] menulis:

Saya agak baru dalam Javascript dan TypeScript (2 minggu) jadi mohon maafkan
saya jika ada solusi yang lebih sederhana di luar sana. Tapi di bawah ini adalah apa yang saya dapatkan
dengan tidak adanya operator pipa. Saya awalnya mencoba memiliki
beberapa kelebihan pipa yang bekerja dengan tipe 2, 3, 4, dll.
parameter, tetapi tidak dapat menemukan cara untuk mendapatkan TypeScript yang berlebihan
resolusi untuk bekerja seperti di C#. Kita bisa memiliki fungsi yang berbeda
pipe1 , pipe2 , dan pipe3 tetapi ini akan sulit untuk bekerja dengan karena Anda harus memilih nama fungsi berdasarkan berapa banyakargumen yang Anda inginkan.
Apakah ada definisi tipe rekursif yang dapat menerimajumlah parameter yang tidak terbatas?

ketik LastOf = [B] meluas [tidak pernah] ?
B :[D] meluas [tidak pernah] ?
D :[F] meluas [tidak pernah] ?

pipa fungsi ( A A,petaA: (a: A) => B,petaB?: (b:B) => C,mapC?: (c: C) => D,petaD?: (d:D) => E,mapE?: (e: E) => F): LastOf { const b = petaA(a);sakelar (petaB) {case undefined: kembalikan b sebagai LastOf ; bawaan: {const c = petaB(b);beralih (petaC) {case undefined: kembalikan c sebagai LastOf ; bawaan: {const d = petaC(c);beralih (petaD) {case undefined: kembalikan d sebagai LastOf ; bawaan: {const e = petaD(d);beralih (petaE) {case undefined: kembalikan e sebagai LastOf ;default: kembalikan mapE(e) sebagai LastOf ; }}}}}}}}

test("peta sekali", () => {
hasil const = pipa(
2,
saya => saya * 10);
berharap(hasil).menjadi(20);
});

test("peta dua kali", () => {
hasil const = pipa(
2,
saya => saya * 10,
saya => the answer is ${i} );
harapkan(hasil).toBe('jawabannya adalah 20');
});

test("peta tiga kali", () => {
hasil const = pipa(
2,
saya => saya * 10,
saya => -i,
i => ({ a: i, b: -i }));
harapkan(hasil).toEqual({ a: -20, b: 20 });
});


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/Microsoft/TypeScript/issues/17718#issuecomment-387878691 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AAZQTLm6LrWe5KVx4aGBFUd4yRUHkkrZks5tw11cgaJpZM4OzVEg
.

Saya baru saja melihat lodash dan Anda benar - fungsi aliran menerima banyak parameter dan diketik dengan kuat. Sepertinya itu tidak dilakukan dalam TypeScript murni. Mereka menggunakan file definisi tipe untuk semua kelebihan. Saya tidak yakin apakah ini lebih baik atau lebih buruk daripada mencoba melakukan semuanya di TypeScript.

@jmagaram semua TS umumnya membuatnya lebih mudah karena inferensi, tetapi jika berhasil, itu berhasil.

@jmagaram Alternatif

interface IPipe<T> {
    readonly value: () => T;
    chain<R>(fn: (x: T) => R): IPipe<R>;
}

function pipe<T>(val: T): IPipe<T> {
    return {
        chain: fn => pipe(fn(val)),
        value: () => val
    };
}

Penggunaan masih akan cukup bersih dan diketik dengan kuat.

pipe(["Hello", "There"])
    .chain(map(x => `${x}!`))
    .chain(xs => {
        ...
    })
    .value()

Saya sangat menghargai kemampuan untuk menambahkan operator khusus. F# memiliki pendekatan yang bagus untuk ini.

Sementara itu, inilah pendekatan yang lebih sederhana tanpa pembungkus:

function pipe<T1>(first:T1):T1
function pipe<T1, T2>(first:T1, second:(a:T1) => T2):T2
function pipe<T1, T2, T3>(first:T1, second:(a:T1) => T2, third:(a:T2) => T3):T3
function pipe<T1, T2, T3, T4>(first:()=>T1, second:(a:T1)=>T2, third:(a:T2)=>T3, fourth:(a:T3)=>T4):T4
function pipe<T1, T2, T3, T4, T5>(first:()=>T1, second:(a:T1)=>T2, third:(a:T2)=>T3, fourth:(a:T3)=>T4, fifth:(a:T4)=>T5):T5
function pipe<T1, T2, T3, T4, T5, T6>(first:()=>T1, second:(a:T1)=>T2, third:(a:T2)=>T3, fourth:(a:T3)=>T4, fifth:(a:T4)=>T5, sixth:(a:T5)=>T6):T6
function pipe<T1, T2, T3, T4, T5, T6, T7>(first:()=>T1, second:(a:T1)=>T2, third:(a:T2)=>T3, fourth:(a:T3)=>T4, fifth:(a:T4)=>T5, sixth:(a:T5)=>T6, seventh:(a:T6)=>T7):T7
function pipe<T1, T2, T3, T4, T5, T6, T7, T8>(first:()=>T1, second:(a:T1)=>T2, third:(a:T2)=>T3, fourth:(a:T3)=>T4, fifth:(a:T4)=>T5, sixth:(a:T5)=>T6, seventh:(a:T6)=>T7, eigth:(a:T7)=>T8):T8
function pipe<T1, T2, T3, T4, T5, T6, T7, T8, T9>(first:()=>T1, second:(a:T1)=>T2, third:(a:T2)=>T3, fourth:(a:T3)=>T4, fifth:(a:T4)=>T5, sixth:(a:T5)=>T6, seventh:(a:T6)=>T7, eigth:(a:T7)=>T8, ninth:(a:T8)=>T9):T9
function pipe<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(first:()=>T1, second:(a:T1)=>T2, third:(a:T2)=>T3, fourth:(a:T3)=>T4, fifth:(a:T4)=>T5, sixth:(a:T5)=>T6, seventh:(a:T6)=>T7, eigth:(a:T7)=>T8, ninth:(a:T8)=>T9, tenth:(a:T9)=>T10):T10
function pipe(first:any, ...args:Function[]):any {
    return (
        args && args.length 
        ? args.reduce(
            (result, next) => next(result),
            first instanceof Function ? first() : first
        )
        : first instanceof Function ? first() : first
    );
}

Ini memberikan:
ts-pipe-example
( untuk info lebih lanjut, lihat di sini )

Yang mengatakan, @graingert +1 Anda benar: lodash sudah memiliki ini untuk komposisi (tetapi bukan pipa):

const getUpperName = 
   _.flow(
      (p: Person) => `${p.FirstName} ${p.LastName}`,
      (s: string) => s.toUpper()
   )

Atau, Anda bisa menambahkan pipa ke Object.prototype:

Object.prototype.pipe = function<Self, Result>(this:Self, next:(value:Self) => Result):Result {
    return next(this)
}

Ini memungkinkan sebagai gantinya:
capture
( untuk info lebih lanjut, lihat di sini )

Semoga ini bisa membantu orang lain!

Itu telah mendarat di Firefox di bawah bendera kompilasi --enable-pipeline-operator .

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Pipeline_operator

Hening sejenak untuk pahlawan yang jatuh, operator pengikat :: , ditutup demi kejahatan |>

Yah saya kira itu di mata yang melihatnya, karena saya lebih suka |> :D

salam untuk raja!

Dan di sini saya pikir itu adalah mimpi pipa

Pipeline pada dasarnya adalah kasus penggunaan sederhana dari Identity Monad. Juga, pipe biasanya compose terbalik sedangkan pipeline lebih seperti pipe yang dipanggil segera.

Bagaimanapun, menantikan untuk melihat ini di TypeScript.

Meskipun memiliki saluran pipa akan membantu, saya merasa mungkin untuk menawarkan kemampuan untuk mendefinisikan operator khusus (fungsi yang namanya mungkin menyertakan karakter khusus, dan yang parameter pertamanya ada di sebelah kirinya) melalui transformator kompiler. Adakah yang tertarik untuk mencoba ini dengan saya, atau memiliki latar belakang tentang ini?

Pada Jumat, 10 Agustus 2018, 02:53 Babak [email protected] menulis:

Pipeline pada dasarnya adalah kasus penggunaan sederhana dari Identity Monad. Juga,
pipa biasanya disusun secara terbalik sedangkan pipa lebih seperti pipa
yang langsung dipanggil.

Bagaimanapun, menantikan untuk melihat ini di TypeScript.


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
https://github.com/Microsoft/TypeScript/issues/17718#issuecomment-411824741 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AFXUx5rwM9wVrpAkHK2BNYkyy74HtWU5ks5uPGkNgaJpZM4OzVEg
.

--

Fungsi infiks ftw

Pada Kamis, 9 Agustus 2018, 23:35 Ben Beattie-Hood, [email protected]
menulis:

Meskipun memiliki saluran pipa akan membantu, saya merasa itu mungkin untuk
menawarkan kemampuan untuk mendefinisikan operator khusus (fungsi yang namanya mungkin
termasuk karakter khusus, dan yang param pertamanya ada di sebelah kirinya) melalui a
transformator kompiler. Siapa pun yang tertarik untuk mencoba ini dengan saya, atau memiliki
beberapa latar belakang ini?

Pada Jumat, 10 Agustus 2018, 02:53 Babak [email protected] menulis:

Pipeline pada dasarnya adalah kasus penggunaan sederhana dari Identity Monad. Juga,
pipa biasanya disusun secara terbalik sedangkan pipa lebih seperti pipa
yang langsung dipanggil.

Bagaimanapun, menantikan untuk melihat ini di TypeScript.


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
<
https://github.com/Microsoft/TypeScript/issues/17718#issuecomment -411824741
,
atau matikan utasnya
<
https://github.com/notifications/unsubscribe-auth/AFXUx5rwM9wVrpAkHK2BNYkyy74HtWU5ks5uPGkNgaJpZM4OzVEg

.

--


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/Microsoft/TypeScript/issues/17718#issuecomment-411919587 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AAZQTHHFbVY5uGCWl-La_P-HF7UN6xPsks5uPLk8gaJpZM4OzVEg
.

ide fungsi infix untuk TypeScript hampir setua TypeScript: https://github.com/Microsoft/TypeScript/issues/2319

Saya tahu banyak orang sangat menginginkan ini, tetapi saya percaya TypeScript tidak boleh mengimplementasikan operator tambahan apa pun selama mereka tidak dalam tahap 3. Hal-hal dapat berubah dan tentu saja ada beberapa pengecualian.

Saya pikir akan layak untuk dicoba sebagai trafo kompiler, hanya untuk memungkinkan komunitas mengeksplorasi ide tersebut, dan untuk mengukur popularitas. Ini adalah fitur yang terdefinisi dengan baik dalam bahasa fungsional lainnya, jadi mungkin cukup aman untuk dijelajahi.

@BenBeattieHood Kami sedang dalam proses menerapkan ini di babel, jadi Anda dapat mengujinya di sana. Jika Anda mengujinya dalam trafo kompiler, lihat proposal saat ini , karena ada beberapa bentuk operator pipa yang sedang kami pertimbangkan.

Saya pikir itu akan membutuhkan banyak pemikiran tentang bagaimana penggunaannya; khusus berkaitan dengan mengetik hal-hal seperti:

function where<T>(predicate: (x: T) => boolean) {
  return function* (items: Iterable<T>): Iterable<T> {
    for (const item of items) {
      if (predicate(item)) {
        yield item;
      }
    }
  };
}

[1, 2, 3] |> where(x=>x> 1)

saat ini dengan where(x => x > 1)([1,2,3]) ia tidak dapat menyimpulkan apa itu x. di atas adalah salah satu alasan saya berharap :: op akan menang, karena (pada pandangan pertama) tampaknya jauh lebih mudah bagi TypeScript untuk menyimpulkan apa itu this

Atau kita bisa melihatnya dengan cara lain: jika dirilis, Ini akan memprioritaskan beberapa masalah inferensi yang dimiliki TS 👍

Kalau ngikutin spek dan berita babel, spek belum set. Ada 2 proposal. Saya yakin tim TypeScript akan menambahkan dukungan ketika spesifikasi selesai

Fungsi infiks ftw

iirc JS menyebut ini "metode".

iirc JS menyebut ini "metode"

@tycho01 Komentar Anda mungkin tidak masuk

@BenBeattieHood Kami sedang dalam proses menerapkan ini di babel, jadi Anda dapat mengujinya di sana. Jika Anda mengujinya dalam trafo kompiler, pasti lihat proposal saat ini, karena ada beberapa bentuk operator pipa yang sedang kami pertimbangkan.

Parser Babel sekarang mendukung proposal jalur pipa pintar.

https://github.com/babel/babel/pull/8289

Ada pembaruan?

Ada pembaruan?

️ TypeScript tidak mengimplementasikan proposal hingga mencapai Tahap 3. Operator saluran pipa saat ini berada di Tahap 1 dan memiliki masalah serius. Informasi itu telah diberikan beberapa kali di utas ini.

contoh masalah serius tolong?

mungkin...

Peringatan: Detail sintaks pipa saat ini belum diselesaikan. Ada dua proposal yang bersaing yang sedang dipertimbangkan.

Ya, itu yang saya anggap sebagai masalah serius.

Akan mengunci yang ini karena semua utas dalam status Menunggu TC39 cenderung berputar begitu saja.

ping!

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

dlaberge picture dlaberge  ·  3Komentar

zhuravlikjb picture zhuravlikjb  ·  3Komentar

Antony-Jones picture Antony-Jones  ·  3Komentar

kyasbal-1994 picture kyasbal-1994  ·  3Komentar

manekinekko picture manekinekko  ·  3Komentar