typescript deduce output from input not working with generic











up vote
1
down vote

favorite
1












While working on better understanding typescript conditional typing I did hit a puzzle: i've got it working for specified type but not conditional type.



I known what i want to do can be achieved with overloading, but the new typescript tool infer and conditional typings allow us to be more generic in our type definitions and therefor not to repeat ourself that much. The following examples, cause simplified can be better expressed as overloads, but when it got more complicate it might not be the case.



Any how, on the principles i do not understand the error i made; here are the two examples:

First the types used



type In<T> = T | T
type Out<Type, T> = Type extends T ? T : T


Then for the specified (working) example:



// No generic version 'string' is passed directly
const foo = <Type extends In<string>>(
x: Type,
): Out<Type, string> => x as any

const a = foo ('abc') // string as expected
const b = foo (['abc', 'def']) // string as expected


And finally the generic (non working) example



// Generic version type should? be inferred
const bar = <T, Type extends In<T>>(
x: Type,
): Out<Type, T> => x as any


const c = bar ('abc') // {} -> Error expected string
const d = bar (['abc', 'def']) // {} -> Error expected string


Might be trivial but i can't find what i'm doing wrong :/



Thanks in advance
Seb










share|improve this question




























    up vote
    1
    down vote

    favorite
    1












    While working on better understanding typescript conditional typing I did hit a puzzle: i've got it working for specified type but not conditional type.



    I known what i want to do can be achieved with overloading, but the new typescript tool infer and conditional typings allow us to be more generic in our type definitions and therefor not to repeat ourself that much. The following examples, cause simplified can be better expressed as overloads, but when it got more complicate it might not be the case.



    Any how, on the principles i do not understand the error i made; here are the two examples:

    First the types used



    type In<T> = T | T
    type Out<Type, T> = Type extends T ? T : T


    Then for the specified (working) example:



    // No generic version 'string' is passed directly
    const foo = <Type extends In<string>>(
    x: Type,
    ): Out<Type, string> => x as any

    const a = foo ('abc') // string as expected
    const b = foo (['abc', 'def']) // string as expected


    And finally the generic (non working) example



    // Generic version type should? be inferred
    const bar = <T, Type extends In<T>>(
    x: Type,
    ): Out<Type, T> => x as any


    const c = bar ('abc') // {} -> Error expected string
    const d = bar (['abc', 'def']) // {} -> Error expected string


    Might be trivial but i can't find what i'm doing wrong :/



    Thanks in advance
    Seb










    share|improve this question


























      up vote
      1
      down vote

      favorite
      1









      up vote
      1
      down vote

      favorite
      1






      1





      While working on better understanding typescript conditional typing I did hit a puzzle: i've got it working for specified type but not conditional type.



      I known what i want to do can be achieved with overloading, but the new typescript tool infer and conditional typings allow us to be more generic in our type definitions and therefor not to repeat ourself that much. The following examples, cause simplified can be better expressed as overloads, but when it got more complicate it might not be the case.



      Any how, on the principles i do not understand the error i made; here are the two examples:

      First the types used



      type In<T> = T | T
      type Out<Type, T> = Type extends T ? T : T


      Then for the specified (working) example:



      // No generic version 'string' is passed directly
      const foo = <Type extends In<string>>(
      x: Type,
      ): Out<Type, string> => x as any

      const a = foo ('abc') // string as expected
      const b = foo (['abc', 'def']) // string as expected


      And finally the generic (non working) example



      // Generic version type should? be inferred
      const bar = <T, Type extends In<T>>(
      x: Type,
      ): Out<Type, T> => x as any


      const c = bar ('abc') // {} -> Error expected string
      const d = bar (['abc', 'def']) // {} -> Error expected string


      Might be trivial but i can't find what i'm doing wrong :/



      Thanks in advance
      Seb










      share|improve this question















      While working on better understanding typescript conditional typing I did hit a puzzle: i've got it working for specified type but not conditional type.



      I known what i want to do can be achieved with overloading, but the new typescript tool infer and conditional typings allow us to be more generic in our type definitions and therefor not to repeat ourself that much. The following examples, cause simplified can be better expressed as overloads, but when it got more complicate it might not be the case.



      Any how, on the principles i do not understand the error i made; here are the two examples:

      First the types used



      type In<T> = T | T
      type Out<Type, T> = Type extends T ? T : T


      Then for the specified (working) example:



      // No generic version 'string' is passed directly
      const foo = <Type extends In<string>>(
      x: Type,
      ): Out<Type, string> => x as any

      const a = foo ('abc') // string as expected
      const b = foo (['abc', 'def']) // string as expected


      And finally the generic (non working) example



      // Generic version type should? be inferred
      const bar = <T, Type extends In<T>>(
      x: Type,
      ): Out<Type, T> => x as any


      const c = bar ('abc') // {} -> Error expected string
      const d = bar (['abc', 'def']) // {} -> Error expected string


      Might be trivial but i can't find what i'm doing wrong :/



      Thanks in advance
      Seb







      typescript






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 9 at 14:21

























      asked Nov 9 at 2:49









      zedryas

      116110




      116110
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          0
          down vote













          Maybe I'm misunderstanding the question (and please clarify if I do, so I can still help you), but wouldn't this simply work?



          function bar<T extends number>(x: T): number
          function bar<T extends string>(x: T): string
          function bar<T extends any>(x: T): T
          function bar<T>(x: T): T {
          return null;
          }

          const c = bar('abc') //string
          const d = bar(['abc', 'def']) //string





          share|improve this answer





















          • Thank you for the quick answer, i did edit my original post - hopefully it will get more clear - since i'm still learning i do have issue pointing the case were a conditional approach will be better that stating all overloads (besides writing less boilerplate code) but i'm pretty sure when you talk of higher kind type that start to be adressable in typescript it will be necessary. I'm trying to understand to go through my way of understanding those complex typings, and i'm blocked in that case by typing not being able to infer a conditional when generic.
            – zedryas
            Nov 9 at 14:25










          • One possible use case is in that question: stackoverflow.com/questions/53228549/…
            – zedryas
            Nov 9 at 15:22











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














           

          draft saved


          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53219153%2ftypescript-deduce-output-from-input-not-working-with-generic%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          0
          down vote













          Maybe I'm misunderstanding the question (and please clarify if I do, so I can still help you), but wouldn't this simply work?



          function bar<T extends number>(x: T): number
          function bar<T extends string>(x: T): string
          function bar<T extends any>(x: T): T
          function bar<T>(x: T): T {
          return null;
          }

          const c = bar('abc') //string
          const d = bar(['abc', 'def']) //string





          share|improve this answer





















          • Thank you for the quick answer, i did edit my original post - hopefully it will get more clear - since i'm still learning i do have issue pointing the case were a conditional approach will be better that stating all overloads (besides writing less boilerplate code) but i'm pretty sure when you talk of higher kind type that start to be adressable in typescript it will be necessary. I'm trying to understand to go through my way of understanding those complex typings, and i'm blocked in that case by typing not being able to infer a conditional when generic.
            – zedryas
            Nov 9 at 14:25










          • One possible use case is in that question: stackoverflow.com/questions/53228549/…
            – zedryas
            Nov 9 at 15:22















          up vote
          0
          down vote













          Maybe I'm misunderstanding the question (and please clarify if I do, so I can still help you), but wouldn't this simply work?



          function bar<T extends number>(x: T): number
          function bar<T extends string>(x: T): string
          function bar<T extends any>(x: T): T
          function bar<T>(x: T): T {
          return null;
          }

          const c = bar('abc') //string
          const d = bar(['abc', 'def']) //string





          share|improve this answer





















          • Thank you for the quick answer, i did edit my original post - hopefully it will get more clear - since i'm still learning i do have issue pointing the case were a conditional approach will be better that stating all overloads (besides writing less boilerplate code) but i'm pretty sure when you talk of higher kind type that start to be adressable in typescript it will be necessary. I'm trying to understand to go through my way of understanding those complex typings, and i'm blocked in that case by typing not being able to infer a conditional when generic.
            – zedryas
            Nov 9 at 14:25










          • One possible use case is in that question: stackoverflow.com/questions/53228549/…
            – zedryas
            Nov 9 at 15:22













          up vote
          0
          down vote










          up vote
          0
          down vote









          Maybe I'm misunderstanding the question (and please clarify if I do, so I can still help you), but wouldn't this simply work?



          function bar<T extends number>(x: T): number
          function bar<T extends string>(x: T): string
          function bar<T extends any>(x: T): T
          function bar<T>(x: T): T {
          return null;
          }

          const c = bar('abc') //string
          const d = bar(['abc', 'def']) //string





          share|improve this answer












          Maybe I'm misunderstanding the question (and please clarify if I do, so I can still help you), but wouldn't this simply work?



          function bar<T extends number>(x: T): number
          function bar<T extends string>(x: T): string
          function bar<T extends any>(x: T): T
          function bar<T>(x: T): T {
          return null;
          }

          const c = bar('abc') //string
          const d = bar(['abc', 'def']) //string






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 9 at 13:29









          Mathias Lykkegaard Lorenzen

          6,4771669139




          6,4771669139












          • Thank you for the quick answer, i did edit my original post - hopefully it will get more clear - since i'm still learning i do have issue pointing the case were a conditional approach will be better that stating all overloads (besides writing less boilerplate code) but i'm pretty sure when you talk of higher kind type that start to be adressable in typescript it will be necessary. I'm trying to understand to go through my way of understanding those complex typings, and i'm blocked in that case by typing not being able to infer a conditional when generic.
            – zedryas
            Nov 9 at 14:25










          • One possible use case is in that question: stackoverflow.com/questions/53228549/…
            – zedryas
            Nov 9 at 15:22


















          • Thank you for the quick answer, i did edit my original post - hopefully it will get more clear - since i'm still learning i do have issue pointing the case were a conditional approach will be better that stating all overloads (besides writing less boilerplate code) but i'm pretty sure when you talk of higher kind type that start to be adressable in typescript it will be necessary. I'm trying to understand to go through my way of understanding those complex typings, and i'm blocked in that case by typing not being able to infer a conditional when generic.
            – zedryas
            Nov 9 at 14:25










          • One possible use case is in that question: stackoverflow.com/questions/53228549/…
            – zedryas
            Nov 9 at 15:22
















          Thank you for the quick answer, i did edit my original post - hopefully it will get more clear - since i'm still learning i do have issue pointing the case were a conditional approach will be better that stating all overloads (besides writing less boilerplate code) but i'm pretty sure when you talk of higher kind type that start to be adressable in typescript it will be necessary. I'm trying to understand to go through my way of understanding those complex typings, and i'm blocked in that case by typing not being able to infer a conditional when generic.
          – zedryas
          Nov 9 at 14:25




          Thank you for the quick answer, i did edit my original post - hopefully it will get more clear - since i'm still learning i do have issue pointing the case were a conditional approach will be better that stating all overloads (besides writing less boilerplate code) but i'm pretty sure when you talk of higher kind type that start to be adressable in typescript it will be necessary. I'm trying to understand to go through my way of understanding those complex typings, and i'm blocked in that case by typing not being able to infer a conditional when generic.
          – zedryas
          Nov 9 at 14:25












          One possible use case is in that question: stackoverflow.com/questions/53228549/…
          – zedryas
          Nov 9 at 15:22




          One possible use case is in that question: stackoverflow.com/questions/53228549/…
          – zedryas
          Nov 9 at 15:22


















           

          draft saved


          draft discarded



















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53219153%2ftypescript-deduce-output-from-input-not-working-with-generic%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Schultheiß

          Verwaltungsgliederung Dänemarks

          Liste der Kulturdenkmale in Wilsdruff