Typescript: اقترح دعم مشغل خط الأنابيب "|>" التالي ES

تم إنشاؤها على ١٠ أغسطس ٢٠١٧  ·  79تعليقات  ·  مصدر: microsoft/TypeScript

ES Next Suggestion Waiting for TC39

التعليق الأكثر فائدة

إنها في المرحلة الأولى الآن

ال 79 كومينتر

اقتراحي المفضل على الإطلاق :( في الوقت الحاضر ، يمكننا بالفعل كتابة برامج مجانية this .

كمرجع ، اقتراح TC39: https://github.com/tc39/proposal-pipeline-operator

لا يعني ذلك أن الاقتراح ليس حتى في المرحلة 0 حتى الآن. إذا تمت إضافته إلى دلالات اللغة ، فمن المحتمل أن تتغير التفاصيل الأخرى.

سيكون هذا أول ما أعتقده (بجانب بعض العناصر القديمة مثل Enum ونظام الوحدة النمطية) ولكن هل يمكن أن يؤدي تطبيق هذا على الطباعة على الطباعة إلى منحها مزيدًا من الوضوح وزيادة الطلب عليها في بقية النظام البيئي ecma؟

أردت فقط مشاركة حل بديل لمشغل خط الأنابيب المفقود مستوحى من https: //vanslaars.io/post/create-pipe-function / ...

SyncPipe مع تقليل متزامن

// 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 مع التخفيض غير المتزامن

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

أنبوب مع اختزال غير متزامن (مبسط)

أستخدم هذا في معظم الأحيان:

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

أتمنى أن تجد هذا مفيدًا!

PublicParadise طريقة أكثر من اللازم: p

بينما أرغب بالتأكيد في رؤية بعض المتغيرات لهذا المشغل في اللغة ، فإن الحاجة المتصورة إليه تأتي من اثنين من القيود المختلفة لـ ECMAScript كما هي حاليًا.

الأول من الصعب جدًا حله أو حتى معالجته باللغة: عدم القدرة على توسيع الكائنات المضمنة بطريقة صحية.

لكن الثاني لا يحتاج إلى دعم على مستوى اللغة على الإطلاق ويمكن في الواقع تصحيحه: يمكن تسمية المكتبة القياسية بفقر الدم.

الحد الأدنى من الحد الأقصى هو فشل كامل.

لماذا يستغرق الأمر شهورًا وأشهرًا من الجدل للحصول على Array.prototype.flatMap في اللغة؟

هذه طريقة واحدة ويجب أن تكون موجودة منذ البداية ويجب أن يكون واضحًا أنه يجب إضافتها.

ربما يكون لدى Array.prototype طريقة groupBy في 6 سنوات.

في الوقت الحالي ، يحتوي هذا على عدد قليل من تطبيقات babel ، والتي نأمل أن تساعد في اقتراح TC39:

إنها في المرحلة الأولى الآن

إذن ، هل هناك أي فرص لهذا الجمال في دخول TS؟ سيكون متماشياً مع F #. <3

على الرغم من وجود استثناءات ، عندما يكون الاقتراح _ مهمًا_ بالنسبة إلى TypeScript وأنواعها ، لا يتم تنفيذ الاقتراح عادةً حتى تصل إلى TC39 المرحلة 3 في TypeScript ، لأنها ليست مستقرة بما يكفي لضمان عدم حدوث انكسارات وانحدارات ملحوظة.

بينما لم يعلق أي من الفريق الأساسي على هذه المشكلة حتى الآن ، إلا أنها لن تكون في رأيي _مهمة _ كافية للنظر فيها للتنفيذ قبل المرحلة الثالثة. أفضل تركيز هو دعم البطل والاقتراح في TC39.

إذا كان لدى TS فقط خيار تمرير هذا المشغل فقط للسماح لـ babel المزود بمكونات إضافية بالتعامل معه.
أو لديها مكونات إضافية خاصة بالنحافة ، مثل post-css do. عدة سنوات في انتظار عامل بدائي هو مجرد الكثير.

garkin : التحدي هنا هو أن TS بحاجة إلى فهم الكود للقيام بعمله في توفير أمان النوع ، والذي لا يتحد جيدًا مع الكود العشوائي الذي لا يفهمه. ما لم يتم الحصول على وحدات ماكرو (# 4892) ، في هذه الحالة يتم تجميعها فقط لتشفير يفهمها. لكنني لا أتوقع ذلك في خريطة الطريق بعد ، حيث لا يزال من الصعب كتابة عدد قليل من أجزاء المكتبة القياسية في أجهزة الصراف الآلي.

الآن بعد أن فهم Babel الكتابة المطبوعة ، يمكنك تشغيله من خلال Babel بعد ذلك
مطبوعة

في 26 أكتوبر 2017 الساعة 19:01 ، كتب "Tycho Grouwstra" [email protected] :

garkin https://github.com/garkin : التحدي هنا هو أن TS بحاجة إلى
فهم الكود للقيام بعمله المتمثل في توفير أمان النوع ، وهو ما لا يفعل ذلك
تتحد جيدًا مع الكود العشوائي الذي لا يفهمه. ما لم يكن للحصول عليه
وحدات الماكرو (# 4892 https://github.com/Microsoft/TypeScript/issues/4892 ) ، في
في هذه الحالة يتم تجميعها فقط لترميز ما يفهمه. لكنني لن أفعل
توقع ذلك على خارطة الطريق تمامًا بعد ، مثل عدد قليل من الأجزاء المعيارية
مكتبة لا تزال تحديا لكتابة أجهزة الصراف الآلي.

-
أنت تتلقى هذا لأنك قمت بتأليف الموضوع.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/Microsoft/TypeScript/issues/17718#issuecomment-339748284 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AAZQTO6UiVHbrM6SRwaBhm8obaa3R7e9ks5swMkCgaJpZM4OzVEg
.

الآن بعد أن فهم Babel الكتابة المطبوعة ، يمكنك تشغيله من خلال Babel بعد ذلك
مطبوعة

ضعف وقت البناء على الرغم من: p

سيكون رائعًا إذا كان الكتابة المطبوعة مجرد مكون إضافي من Babel ، فلن تحتاج إلى ذلك
عبر كلا البرنامجين

في 26 أكتوبر 2017 الساعة 20:16 ، كتب "AlexGalays" [email protected] :

الآن بعد أن فهم Babel الكتابة المطبوعة ، يمكنك تشغيله من خلال Babel بعد ذلك
مطبوعة

ضعف وقت البناء على الرغم من: p

-
أنت تتلقى هذا لأنك قمت بتأليف الموضوع.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/Microsoft/TypeScript/issues/17718#issuecomment-339769856 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AAZQTEArBw8jj0BcZFM2yLj5ErfbtNrgks5swNqagaJpZM4OzVEg
.

graingert : إنه خيار جيد ، سأقوم بالتحقيق في هذا الأمر.
لسوء الحظ ، لن تعمل مع واجهة برمجة تطبيقات Language Service API التي تستخدمها VisualStudioCode و Webstorm و IDEs الأخرى.

فيما يتعلق بـ "ملحقات TS" يمكن للمرء أن يحقق النتيجة المرجوة بسهولة ، دعنا نقول ، ناقل بسيط (مسبق) لمشغل الأنابيب الذي يفهم بناء جملة TS وينتج مكافئًا مكتوبًا قويًا للبيان. سيتم تجميعها على ما يرام مع فحص النوع وما إلى ذلك.

يمكن أن يبدو تكوين حزمة الويب الخاصة بذلك على النحو التالي:

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

التحدي الوحيد ، كما أشار garkin ، هو أن خدمة TS لن تكون قادرة على ربط الأجزاء المنقولة بالملف المصدر الأصلي ، فإن IDEs التي تستخدم الخدمة لن تعمل بشكل صحيح حتى إذا كانت تعرف بالفعل المشغل (ES Next تمكين بناء الجملة أو شيء من هذا القبيل).

ربما إذا أنشأنا NFR (أو ربما يوجد بالفعل واحد؟) لخدمة TS لدعم خرائط المصدر التراكمية ليتم تطبيقها بين الملف المصدر والنتيجة المترجمة التي يتم تغذيتها للمترجم ، فسيكون هذا والإضافات الأخرى ممكنة دون التأثير على بقية المجتمع ، والأهم من ذلك ، دون إضافة المزيد من التعقيد على الفريق الأساسي للتعامل معه.


أيضًا ، لا يمكنني تحديد مدى ارتباط # 13940 بهذا ولكن يبدو أنها بداية جيدة نحو المكونات الإضافية الأكثر تعقيدًا. ومع ذلك ، يبدو لي أن نهج خريطة المصدر لا يزال بديلاً أبسط بكثير نظرًا لأن مترجم الحد الأدنى (قبل) لن يحتاج إلى سياق المشروع في معظم الحالات لأنه سيكون من السهل إلى حد ما استخراج كتل تدوين النوع (إن وجدت) من بيان نص خام ثم إعادة كتابته بطريقة يمكن التحكم في التدفق من خلالها الإشارة إلى أنواع الإدخال / الإخراج المحددة للجزء المنقول.


أخيرًا وليس آخرًا ، هل يمكن لأي شخص أن يوجهني إلى الموضوع _official_ (إن وجد) بخصوص هذا النوع من المكونات الإضافية؟

أحتاج أن أقول إنني أقدر حقًا الطريقة الهادئة لتقديم مقترحات جديدة وأفضل أدوات كتابة النصوص المتجانسة وأدوات LessCSS أكثر من الألعاب الأولمبية الإضافية الخاصة بـ Flow + Babel و Post-CSS.

إنها قابلية للتخصيص وسرعة الحصول على ميزات جديدة بتكلفة انتفاخ التجزئة ومجال خبرة.

مشغل الأنابيب هو مثل دواء دخول إلى العالم الوظيفي ، فهو يجعلني أقول وأتمنى أشياء غريبة.

إذن ، هناك # 14419 وحتى بعض الآثار العملية المفيدة بالفعل. لا ينبغي أن يكون من الصعب دمج هؤلاء مع ts-loader .

تكامل المحولات tsconfig.json (وكذلك واجهة برمجة تطبيقات Language Service ، وليس فقط تخصيص tsc ) تم رفض # 14654 _ على المدى القصير_.

يناقش 11976 ملحقات خدمة اللغة ، والتي تبدو وكأنها أدوات فحص فقط.

16607 يقترح تمديد تلك الملحقات للمحولات.

PublicParadise أو استخدم فقط flow أو Rambda's pipe ؟

على أي حال ، سيكون من الرائع جدًا أن يتم دعمك في TS. أنا أحب الأنماط الوظيفية التي يدعمها JS (خاصة مع استدلال نوع TS) ، لكن بعض الأنماط لا تقرأ بشكل جيد للغاية. سيكون هذا ضخمًا لأن مكتبات TS الكبيرة مثل RxJS و IxJS تتجه نحو تكوين وظيفي خالٍ من النقاط على امتداد / وراثة النموذج الأولي ، مما يجعل هز الشجرة أفضل ودعمًا للمشغلين المخصصين.

felixfbecker تقصد رامدا pipe ؟ أحتاج إلى المحاولة مرة أخرى ، ولكن من الناحية التاريخية ، فإن ramda هو lib الأول في JS ، إنه ديناميكي للغاية ويصعب كتابته (مثل لوداش) ، ويضاعف من ذلك حقيقة أن TS كانت تواجه الكثير من المشاكل في الاستدلال من قيم إرجاع الوظيفة (ربما كانت كذلك) تم إصلاحه مؤخرًا ، لكن لست متأكدًا)
لا أستخدم lodash لأنه سيء ​​التصميم ، حيث يخلط بين الوظائف المتغيرة والثابتة في مساحة اسم كبيرة واحدة.

إنه في الواقع يعمل بشكل جيد إذا لم تكن وظائفك وسلاسلك مجنونة للغاية:

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

إنه في الواقع يعمل بشكل جيد إذا لم تكن وظائفك وسلاسلك مجنونة للغاية

اسمح لي بالتأهل لـ "لست مجنونًا للغاية" هناك: تتعطل الأشياء إذا كانت وظائفك تحتوي على أدوية عامة (راجع https://github.com/types/npm-ramda/issues/86) ، على سبيل المثال R.pipe(R.identity) .

أيضًا ، لنكن واضحين ، الاقتراح هو المرحلة الأولى. أصبح الفريق الأساسي أكثر خجلًا بشأن تقديم الأشياء قبل المرحلة 3. المصممون جزء من المثال. على الرغم من تمييزها على أنها _تجريبية_ ، فقد تقدمنا ​​جميعًا وقمنا بتمكين هذه العلامة وكتبنا كل كود الإنتاج لدينا باستخدامها. لقد ارتد الاقتراح الآن وهناك بعض التغييرات الأساسية في بناء الجملة والدلالات التي ستعني أننا سنضطر جميعًا إلى إعادة تشكيل الكود الخاص بنا مما يضع الفريق الأساسي في موقف صعب ، لأنهم إذا كانوا _فقط _ يدعمون النهائي أكثر من أن يتم كسر بناء الجملة في اليوم الذي يتم فيه إصداره ، أو إذا احتفظوا بالعناصر القديمة ، فقد تجعل التغييرات الأخرى في المترجم من الصعب دعم الصيغتين ، وفي النهاية تريد التخلص من العناصر القديمة ، ولكن متى .. . 💥 💥

لذا ، فإن أفضل شيء تفعله مع الميزات المستندة إلى المعايير مثل هذا ، ليس مناقشة دعم TypeScript أو نقص الدعم هنا ، بل العثور على مندوب TC39 المحلي الودود والدعوة إلى أن هذه الميزة مهمة حقًا بالنسبة لك وكذلك المشاركة في محادثة الاقتراح المرتبطة أعلاه على GitHub. كلما تم حل الدلالات بشكل أسرع وكلما وصلت إلى المرحلة 3 بشكل أسرع ، كلما كان بإمكاننا جميعًا الحصول على أشياء لطيفة بشكل أسرع!

الآن بعد أن أصبح لدى rxjs عوامل تشغيل قابلة للتأجير ، ستكون هذه ميزة أكثر روعة في Typecript.
https://github.com/ReactiveX/rxjs/blob/master/doc/lettable-operators.md

هل يمكننا الاستعانة بشخص من فريق TS لإلقاء بعض الضوء على هذا الطلب؟

لقد قاموا بوضع علامة عليه ES Next و Suggestion ... يمكنني اقتباس فصل وآية من المواقع الأخرى حيث قاموا بالتعليق على مقترحات ES Next ومتى وكيف يتم تنفيذها ...

تعليق منهم لن يغير أي شيء. هل تعتقد أنهم يعملون عليها سرًا وراء الكواليس ، في انتظار طرحها على المجتمع؟ غالبًا لا يدخلون في قضية ما إذا لم يكن هناك شيء يضيفونه ... لا يوجد شيء يمكن إضافته إلى ما قيل بالفعل.

في هذه المرحلة ، أعتقد أنه سيكون من المفيد جدًا وجود مكونات إضافية تعمل على توسيع اللغة. أضف ميزات لن تكون جزءًا من جوهر اللغة ستكون جزءًا من هذه المكونات الإضافية.

aminpaks أنا لا أحب الفكرة حقًا لأنها قد تؤدي سريعًا إلى طفولة (كما في برج بابل وليس مترجم Babeljs الممتاز)

نظرًا لأن المكونات الإضافية قد تتضمن سلوكًا على مستوى النوع ، يصبح من الصعب فهم معنى البرامج ، وسيتطلب التعامل مع تبعيات مستوى المصدر عددًا من الميزات المعقدة ولكنها مفيدة للغاية التي يفتقر إليها TypeScript حاليًا.

بقدر ما أحب أن يكون هذا في كل مكان ممكن ، يسعدني أن TS تتخذ نهجًا أكثر تحفظًا لتنفيذ ميزات جديدة والالتزام بالمعايير. هذا الموقف يجعل TS أكثر جاذبية بشكل عام للأشخاص مثلي الذين يهتمون بشدة بالانحراف عن المعيار ولكنهم يستمتعون بالميزات المتقدمة التي يوفرها النقل قبل اعتماد بائع المتصفح / محرك JS (ولكن ليس بالضرورة قبل التوحيد القياسي). إنه عمل موازنة دقيق.

أنا شخصياً لست مؤيداً لمشغل خطوط الأنابيب على حساب مشغل الربط. يتعلق الأمر بالقراءة حقًا.

معطى:

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

ربط عملية:

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

خط الأنابيب المرجع:

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

فريق ts محق في عدم الإزعاج حتى المرحلة 3 ؛ وحتى مع ذلك ، لا يزال من الممكن سحب مقترحات المرحلة 3 (مثل SIMD). إنه لأمر مخز أنه لا يمكننا الحصول على مكونات إضافية - يتم تمرير "المخاطر" إلى المطور الفردي. هناك الكثير من حالات الاستخدام الأخرى للمكونات الإضافية أيضًا ، ليس أقلها لدعم أشياء مثل ملفات .vue التي تحتوي على نص مكتوب.

تضمين التغريدة على الرغم من أنني أفضل وجود مشغل خطوط الأنابيب ، بدلاً من عدم وجود سكر على الإطلاق ، إلا أنه مستوحى من اللغات التي يتم فيها تجهيز الوظائف تلقائيًا وحيث يتم بناء المكتبات حول الاستفادة من ذلك. كما يفترض أيضًا أن طرق خطوط الأنابيب ليست أعضاء في قيم خطوط الأنابيب.

لذلك بعد ذلك سيكون لديك

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

ثم تكتب

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

ولكن نظرًا لأن JavaScript لا يعمل تلقائيًا ولا يمكنه معالجة الوظائف ، يبدو أنه يعمل بشكل جيد فقط مع المكتبات المصممة مع مراعاة الاهتمام.

قد أكون مخطئًا بشأن هذا ، فأنا لست حديثًا كثيرًا عن الاقتراح.

بعد ذلك ، قد تصبح المكتبة الجديدة التي توفر وظائف استخدام مكتملة بشكل افتراضي هي المعيار الجديد: p

AlexGalays أعتقد أن هذا محتمل إذا مر هذا. طالما أنه ليس جزءًا من مؤامرة تخريبية لتحويل JavaScript إلى OCaml ، فكل شيء على ما يرام.

MeirionHughes المثال الخاص بك غير صحيح. لا تستخدم دالة where this على الإطلاق ، لذا لن يعمل عامل الربط. لدى عامل الربط أيضًا الكثير من الأسئلة المفتوحة لسلامة النوع. هل سيسمح لـ where بالوصول إلى الملكيات الخاصة من this مثل طريقة الفصل؟ إذا لم يكن كذلك ، فما الفائدة من استخدام this ؟ إذا كانت الإجابة بنعم ، فإن تغيير الخصائص الخاصة يعد فجأة تغييرًا جذريًا ، والذي يقضي تمامًا على الغرض من الممتلكات الخاصة.
أنت تذكر أيضًا أن بناء الجملة أقل قابلية للقراءة ، ولكن على سبيل المثال حذف الأقواس في مثال عامل الربط الخاص بك ولكن أضف أقواسًا غير ضرورية في مثال خط الأنابيب. ولن يعمل مشغل خط الأنابيب بالطبع على الإطلاق بوظائف مكتوبة للربط ، ولكنه سيعمل بشكل جيد للوظائف الممزوجة ، مثل مشغلي rxjs أو ramda أو Lodash / fp.

aluanhaddad إلى جانب جميع مكتبات fp ، تعد RxJS مثالًا لمكتبة مستخدمة على نطاق واسع انتقلت من المشغلين في النماذج الأولية (التي لديها الكثير من المشاكل ، معظمها حول اهتزاز الأشجار والسلامة العامة) إلى المشغلين كوظائف كاري. ربما لا تختار معظم المكتبات هذه الطريقة الآن _ لأننا لا نمتلك صياغة جيدة لها.

felixfbecker أنت يعشش الوظائف الناتجة التي تحصل على الأنابيب قد غيّر رأيي تمامًا.

هل فكر أي شخص أو يقوم بتنفيذ محول مخصص للحصول على دعم خط الأنابيب قبل ذلك بقليل؟ من مظهرها يمكن أن يتم ذلك عبر محول مخصص يحتوي ببساطة على بابل transpile _ just_ جزء خط الأنابيب نفسه. يمكنك بعد ذلك تنفيذه عبر: https://github.com/cevek/ttypescript

هل هذا احتمال؟ هل تستخدم التحويلات المخصصة لاستخدام بناء الجملة المدعوم من Babel ، مع الحفاظ على عمل أشياء مثل أدوات TypeScripts؟

يمكن؟ هناك إعداد مسبق يتعامل فقط مع المقترحات 0-2: https://www.npmjs.com/package/babel-preset-proposal-typescript - فهذا يعني أنك وضعت هذا قبل إرساله إلى الكتابة المطبوعة. من المحتمل أن تكون محسوسًا على الرغم من ذلك. ومع ذلك ، مع https://github.com/cevek/ttypescript#visual -studio-code قد تفلت من العقاب.

MeirionHughes أنا سعيد لأنه كان مفيدًا ❤️.
الآن نحتاج فقط إلى # 6606 حتى نتمكن من تحويل أساليب النماذج الأولية التعسفية إلى وظائف خالية من العيوب!

TypeScript هو تحويل بابل الآن ، أعتقد أنه يجب أن تكون هناك طريقة للتسلسل في خط الأنابيب قبل تمرير TypeScript. ليس لدي أي فكرة عن كيفية عمل ذلك مع خادم اللغة.

أضفت تنفيذًا مستضافًا ذاتيًا لـ TS # 22816

بصفتك أحد الأشخاص الذين يدفعون باتجاه عامل تشغيل خطوط الأنابيب ، أتوسل إليكم: من فضلك لا تنفذ هذا في TypeScript حتى تتقدم أكثر. ما زلنا نناقش اقتراحين محتملين ، وهما غير متوافقين بشكل أساسي مع بعضهما البعض ، لذا فإن TypeScript تتوسل لعالم يتألم إذا نفذت هذا مبكرًا.

إذا كنت مهتمًا بهذا الاقتراح ، فقم بإلقاء نظرة على الريبو هنا وشارك: https://github.com/tc39/proposal-pipeline-operator/ نحن نحب ملاحظاتك! ونحن نعمل على مكونات Babel الإضافية للمقترحات المختلفة ، لذا سيكون لديك فرصة لتجربتها في مشاريعك (التي لا تحتوي على TypeScript).

لكن الاقتراح ليس جاهزًا للهبوط في شيء مثل TypeScript حتى الآن.

نحن بالتأكيد لا ندمج هذا.

هل يمكننا الحصول على شيء مثل https://github.com/babel/babel-eslint ، والذي يسمح لنا بالاستمرار في استخدام الميزات التي يدعمها Babel ، وجعل فحص الكتابة يعمل بعد إلغاء الميزات غير المدعومة بواسطة TypeScript؟

masaeedu نعم! هذه

MeirionHughes مع اقتراح التطبيق الجزئي يصبح أسهل:

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

bernatmv : fwiw هناك شيء قريب منه يعمل اليوم.

@ tycho01 لكن ليس في TypeScript ، حتى تحصل على 2.8 كتابة: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/25067

jeremejevsbernatmv في الواقع، R.__ تم كتابتها باستخدام codegen في الآلية الوقائية الوطنية، رمضة . أفضل الطرق باستخدام 2.8 مرحبًا!

أنا جديد إلى حد ما على Javascript و TypeScript (أسبوعين) لذا أرجوك سامحني إذا كان هناك حل أبسط. لكن فيما يلي ما توصلت إليه في غياب مشغل خطوط الأنابيب. حاولت في الأصل الحصول على أحمال زائدة متعددة pipe والتي عملت مع معلمات النوع 2 ، 3 ، 4 ، إلخ ، ولكن لم أستطع معرفة كيفية الحصول على دقة التحميل الزائد من TypeScript للعمل كما هو الحال في C #. يمكن أن يكون لدينا وظائف مختلفة pipe1<A,B> ، pipe2<A,B,C> ، و pipe3<A,B,C,D> لكن هذا سيكون صعبًا للعمل معه لأنه سيتعين عليك اختيار اسم الوظيفة بناءً على عدد الوسائط التي تستخدمها مطلوب. هل يوجد حل آمن للنوع أبسط مما اقترحته أدناه؟ هل يوجد تعريف للنوع العودي يمكن أن يقبل عددًا غير محدود من المعلمات؟ هل أستخدم أنواع الشروط بشكل صحيح؟

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

اعتقدت أن _.flow في لوداش / fp قد كتب هذا بالفعل؟

في الأربعاء ، 9 مايو 2018 ، 22:19 jmagaram ، كتب [email protected] :

أنا جديد إلى حد ما على جافا سكريبت وتيبي سكريبت (أسبوعين) لذا أرجوك سامحني
لي إذا كان هناك حل أبسط هناك. لكن أدناه هو ما توصلت إليه
مع في حالة عدم وجود مشغل خطوط الأنابيب. حاولت في الأصل أن أمتلك
أحمال زائدة متعددة من الأنابيب التي تعمل مع النوع 2 ، 3 ، 4 ، إلخ
المعلمات ، ولكن لا يمكن معرفة كيفية الحصول على TypeScript الزائد
القرار للعمل كما هو الحال في C #. يمكن أن يكون لدينا وظائف مختلفة
الأنابيب 1 ، والأنابيب 2 3 ولكن هذا سيكون صعبًا اعمل مع لأنه سيتعين عليك اختيار اسم الوظيفة بناءً على عدد ملفاتالحجج التي تريدها.
هل يوجد تعريف للنوع العودي يمكن أن يقبل امتداد الملفعدد غير محدود من المعلمات؟

اكتب LastOf = [ب] يمتد [أبدا]؟
ب :[د] يمتد [أبدا]؟
د :[F] يمتد [أبدا]؟

أنبوب وظيفي ( أ: أ ،الخريطة أ: (أ: أ) => ب ،mapB ؟: (ب: ب) => ج ،mapC ؟: (c: C) => D،mapD ؟: (d: D) => E،mapE ؟: (e: E) => F): LastOf { const ب = mapA (أ) ؛التبديل (الخريطة ب) {حالة غير معرفة: إرجاع b كـ LastOf ؛ إفتراضي: {const ج = mapB (ب) ؛التبديل (mapC) {حالة غير معرفة: إرجاع c كـ LastOf ؛ إفتراضي: {const د = mapC (ج) ؛التبديل (mapD) {حالة غير معرفة: إرجاع d كـ LastOf ؛ إفتراضي: {const e = mapD (د) ؛التبديل (الخريطة) {حالة غير محددة: إرجاع e كـ LastOf ؛الافتراضي: إرجاع mapE (e) كـ LastOf ؛ }}}}}}}}

اختبار ("الخريطة مرة واحدة"، () => {
نتيجة كونست = أنبوب (
2 ،
أنا => أنا * 10) ؛
توقع (نتيجة) .toBe (20) ؛
}) ؛

اختبار ("الخريطة مرتين"، () => {
نتيجة كونست = أنبوب (
2 ،
أنا => أنا * 10 ،
i => the answer is ${i} ) ؛
توقع (نتيجة) .toBe ("الإجابة هي 20") ؛
}) ؛

اختبار ("الخريطة ثلاث مرات" ، () => {
نتيجة كونست = أنبوب (
2 ،
أنا => أنا * 10 ،
أنا => -أنا ،
i => ({a: i، b: -i})) ؛
توقع (نتيجة) .toEqual ({a: -20، b: 20}) ؛
}) ؛

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/Microsoft/TypeScript/issues/17718#issuecomment-387878691 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AAZQTLm6LrWe5KVx4aGBFUd4yRUHkkrZks5tw11cgaJpZM4OzVEg
.

لقد نظرت للتو إلى اللوداش وأنت على صواب - وظيفة التدفق تقبل العديد من المعلمات ويتم كتابتها بقوة. Iit لا يبدو أنه تم في نقي TypeScript. يستخدمون ملف تعريف النوع لجميع الأحمال الزائدة. لست متأكدًا مما إذا كان هذا أفضل أم أسوأ من محاولة القيام بكل ذلك في TypeScript.

jmagaram كل TS بشكل عام يجعل الأمر أسهل بسبب الاستدلال ، ولكن إذا كان يعمل.

jmagaram يمكن أن يبدو بديل الكتابة المطبوعة الخالص الأبسط نوعًا ما شيئًا كهذا.

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

سيظل الاستخدام نظيفًا إلى حد ما ومكتوبًا بقوة.

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

سأقدر حقًا القدرة على إضافة عوامل تشغيل مخصصة. F # لديه نهج لطيف لهذا الغرض.

في غضون ذلك ، إليك طريقة أبسط بدون التفاف:

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

هذا يعطي:
ts-pipe-example
( لمزيد من المعلومات ، انظر هنا )

ومع ذلك ، فإن graingert +1 أنت على حق: فلوداش لديه هذا بالفعل للتكوين (ولكن ليس الأنبوب):

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

بدلاً من ذلك ، يمكنك بدلاً من ذلك إضافة أنبوب إلى Object.prototype:

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

هذا يسمح بدلاً من ذلك بما يلي:
capture
( لمزيد من المعلومات ، انظر هنا )

أتمنى أن يساعد هذا الآخرين!

لقد هبط في Firefox تحت علامة تجميع --enable-pipeline-operator .

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

دقيقة صمت للبطل الذي سقط ، عامل الربط :: ، أغلق لصالح الشر |> 😢

حسنًا ، أعتقد أنه في عين الناظر ، لأنني أفضل |> : D

تحية للملك!

وهنا اعتقدت أنه كان حلمًا كاذبًا

خط الأنابيب هو في الأساس حالة استخدام بسيطة لـ Identity Monad. أيضًا ، عادةً ما يكون pipe compose في الاتجاه المعاكس بينما pipeline يشبه pipe الذي يتم استدعاؤه على الفور.

على أي حال ، أتطلع إلى رؤية هذا في كتابته المطبوعة.

على الرغم من أن وجود خط أنابيب سيكون مفيدًا ، إلا أنني أشعر أنه سيكون من الممكن تقديم القدرة على تحديد المشغلين المخصصين (الوظائف التي قد يتضمن اسمها أحرفًا خاصة ، وتكون معلماتها الأولى على اليسار) عبر محول مترجم. أي شخص مهتم بتجربة هذا معي ، أو لديه خلفية عن هذا؟

في يوم الجمعة ، 10 أغسطس ، 2018 ، 02:53 كتب Babak [email protected] :

خط الأنابيب هو في الأساس حالة استخدام بسيطة لـ Identity Monad. ايضا،
عادة ما يتم تكوين الأنبوب في الاتجاه المعاكس بينما يشبه خط الأنابيب الأنبوب
التي يتم استدعاؤها على الفور.

على أي حال ، أتطلع إلى رؤية هذا في كتابته المطبوعة.

-
أنت تتلقى هذا لأنك علقت.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/Microsoft/TypeScript/issues/17718#issuecomment-411824741 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AFXUx5rwM9wVrpAkHK2BNYkyy74HtWU5ks5uPGkNgaJpZM4OzVEg
.

-

وظائف Infix ftw

في الخميس ، 9 أغسطس 2018 ، الساعة 23:35 بن بيتي هود ، [email protected]
كتب:

على الرغم من أن وجود خط أنابيب سيكون مفيدًا ، إلا أنني أشعر أنه سيكون من الممكن ذلك
تقدم القدرة على تحديد عوامل التشغيل المخصصة (الوظائف التي قد يكون اسمها
تتضمن أحرفًا خاصة ، والتي تكون بارامتها الأولى على اليسار) عبر a
محول المترجم. أي شخص مهتم بتجربة هذا معي ، أو لديه
بعض المعلومات الأساسية عن هذا؟

في يوم الجمعة ، 10 أغسطس ، 2018 ، 02:53 كتب Babak [email protected] :

خط الأنابيب هو في الأساس حالة استخدام بسيطة لـ Identity Monad. ايضا،
عادة ما يتم تكوين الأنبوب في الاتجاه المعاكس بينما يشبه خط الأنابيب الأنبوب
التي يتم استدعاؤها على الفور.

على أي حال ، أتطلع إلى رؤية هذا في كتابته المطبوعة.

-
أنت تتلقى هذا لأنك علقت.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
<
https://github.com/Microsoft/TypeScript/issues/17718#issuecomment -411824741
و
أو كتم الخيط
<
https://github.com/notifications/unsubscribe-auth/AFXUx5rwM9wVrpAkHK2BNYkyy74HtWU5ks5uPGkNgaJpZM4OzVEg

.

-

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/Microsoft/TypeScript/issues/17718#issuecomment-411919587 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AAZQTHHFbVY5uGCWl-La_P-HF7UN6xPsks5uPLk8gaJpZM4OzVEg
.

إن فكرة وظائف infix للطباعة المطبوعة قديمة قدم النص المطبوع: https://github.com/Microsoft/TypeScript/issues/2319

أعرف أن الكثير من الناس يريدون هذا أمرًا سيئًا حقًا ، لكنني أعتقد أن TypeScript لا ينبغي أن ينفذ أي عامل إضافي طالما أنهم ليسوا في المرحلة 3. يمكن أن تتغير الأشياء وبالطبع هناك بعض الاستثناءات.

أعتقد أنه سيكون من المفيد المحاولة كمحول مترجم ، فقط للسماح للمجتمع باستكشاف الفكرة ، وقياس الشعبية. إنها ميزة محددة جيدًا في اللغات الوظيفية الأخرى ، لذا قد يكون استكشافها آمنًا تمامًا.

BenBeattieHood نحن بصدد تنفيذ هذا في Babel ، لذا ستتمكن من اختباره هناك. إذا قمت باختباره في محول مترجم ، فقم بالتأكيد بإلقاء نظرة على العروض الحالية ، حيث توجد بعض أشكال مشغل خطوط الأنابيب التي ندرسها.

أعتقد أنه سيحتاج إلى الكثير من التفكير حول كيفية استخدامه ؛ على وجه التحديد فيما يتعلق بكتابة أشياء مثل:

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)

في الوقت الحالي مع where(x => x > 1)([1,2,3]) لا يمكن استنتاج ما هو x. ما ورد أعلاه هو أحد الأسباب التي كنت آمل أن يفوز بها :: op ، لأنه (للوهلة الأولى) يبدو أنه من الأسهل كثيرًا بالنسبة للطباعة أن تستنتج ما هو this

أو يمكننا رؤيتها بطريقة أخرى: إذا تم إصدارها ، فسوف تعطي الأولوية لبعض مشكلات الاستدلال التي تواجهها TS 👍

إذا اتبعت المواصفات وأخبار بابل ، فلن يتم تعيين المواصفات بعد. هناك 2 اقتراح. أنا متأكد من أن فريق الكتابة المطبوعة سيضيف الدعم عند الانتهاء من المواصفات

وظائف Infix ftw

تسمي iirc JS هذه "الطرق".

تسمي iirc JS هذه "الطرق"

@ tycho01 إن تعليقك ربما يكون لسانًا في الخد ، لكنني أعتقد أن هذه ليست نفس الشيء تمامًا. لا يمكنك فقط تصدير دالة ثنائية من مكان ما وتطبيقها على قيمتين ؛ يجب تطعيم المعرفة حول كل دالة ستقوم بالتلاعب بالقيمة في القيمة نفسها ، إما كخاصية مباشرة أو على نموذج أولي. هذا غير مريح في السيناريوهات العملية.

BenBeattieHood نحن بصدد تنفيذ هذا في Babel ، لذا ستتمكن من اختباره هناك. إذا قمت باختباره في محول مترجم ، فقم بالتأكيد بإلقاء نظرة على العروض الحالية ، حيث توجد بعض أشكال مشغل خطوط الأنابيب التي ندرسها.

يدعم محلل Babel الآن اقتراح خط الأنابيب الذكي.

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

أي تحديثات؟

أي تحديثات؟

🤦‍♂️ لا تنفذ TypeScript الاقتراح حتى تصل إلى المرحلة 3. مشغل خطوط الأنابيب هو المرحلة الأولى حاليًا ولديه مشكلات خطيرة. تم توفير هذه المعلومات عدة مرات في هذا الموضوع.

مثال على القضايا الجادة من فضلك؟

يمكن...

⚠ تحذير: تفاصيل بناء جملة خط الأنابيب غير مستقرة حاليًا. هناك نوعان من المقترحات المتنافسة قيد النظر.

نعم ، هذا ما أعتبره قضية خطيرة.

الذهاب إلى قفل هذا لأن جميع سلاسل الرسائل في TC39 تميل إلى الانتقال في دوائر.

بينغ!

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات