Way to define a type in typescript like [one of union of interfaces] & {//atrributes}












0














// The way types defined:

interface SudoA {
foo: string;
}

interface SudoB {
bar: string;
}

type Sudo = SudoA | SudoB;

type SuperSudo = Sudo & {
super: boolean;
}

const baz: SuperSudo = {

}
// typescript (3.1.6) says i have to define both `bar` and `foo` for the object


What I expect is that to put super attribute and other attributes (coming from Sudo type) should be optional. The question; is this a wrong expectation? Regardless if yes or no how is this achieved?



Edit

Corrected the type of baz, my mistake :/.

What I am expecting is for SuperSudo defining only super attribute should be enough and other attributes coming from union of interfaces should be optional.



I can define a new type like
type SuperSudo<T> = T & {} but this ends up using SuperSudo<T>which I find quite verbose.



Edit2

Changed the title










share|improve this question
























  • I don't quite understand what you're saying. baz is in error because it needs to have at least one of the foo or bar properties in order to be SudoA | SudoB. And since baz is of type Sudo I don't understand how SuperSudo has anything to do with it. Could you rephrase the question or add more examples of what you expect to work and what you expect to report an error?
    – jcalz
    Nov 21 '18 at 0:43










  • When i understand your question, then you find the answer in the documentation of the release notes 2.8 typescript. typescriptlang.org/docs/handbook/release-notes/… Here is everything covered what you need to know about typings and how to make attributes optional / readonly / modify datatypes in inheritance.
    – Sly321
    Nov 21 '18 at 0:59






  • 1




    You want SuperSudo to only require super and not require any of the properties from SudoA or SudoB? What if SudoA has two or more properties (e.g., {foo: string, qux: number})? Can a SuperSudo contain just one of those properties (e.g., {super: true, foo: "a"})? It's still not clear to me what you're trying to do. Maybe you're looking for something like type AllKeys<T> = T extends any ? keyof T : never; type SuperSudo = {[K in AllKeys<Sudo>]?: Extract<Sudo, Record<K, any>>[K]} & {super: boolean;} but it's hard to be sure.
    – jcalz
    Nov 21 '18 at 1:48
















0














// The way types defined:

interface SudoA {
foo: string;
}

interface SudoB {
bar: string;
}

type Sudo = SudoA | SudoB;

type SuperSudo = Sudo & {
super: boolean;
}

const baz: SuperSudo = {

}
// typescript (3.1.6) says i have to define both `bar` and `foo` for the object


What I expect is that to put super attribute and other attributes (coming from Sudo type) should be optional. The question; is this a wrong expectation? Regardless if yes or no how is this achieved?



Edit

Corrected the type of baz, my mistake :/.

What I am expecting is for SuperSudo defining only super attribute should be enough and other attributes coming from union of interfaces should be optional.



I can define a new type like
type SuperSudo<T> = T & {} but this ends up using SuperSudo<T>which I find quite verbose.



Edit2

Changed the title










share|improve this question
























  • I don't quite understand what you're saying. baz is in error because it needs to have at least one of the foo or bar properties in order to be SudoA | SudoB. And since baz is of type Sudo I don't understand how SuperSudo has anything to do with it. Could you rephrase the question or add more examples of what you expect to work and what you expect to report an error?
    – jcalz
    Nov 21 '18 at 0:43










  • When i understand your question, then you find the answer in the documentation of the release notes 2.8 typescript. typescriptlang.org/docs/handbook/release-notes/… Here is everything covered what you need to know about typings and how to make attributes optional / readonly / modify datatypes in inheritance.
    – Sly321
    Nov 21 '18 at 0:59






  • 1




    You want SuperSudo to only require super and not require any of the properties from SudoA or SudoB? What if SudoA has two or more properties (e.g., {foo: string, qux: number})? Can a SuperSudo contain just one of those properties (e.g., {super: true, foo: "a"})? It's still not clear to me what you're trying to do. Maybe you're looking for something like type AllKeys<T> = T extends any ? keyof T : never; type SuperSudo = {[K in AllKeys<Sudo>]?: Extract<Sudo, Record<K, any>>[K]} & {super: boolean;} but it's hard to be sure.
    – jcalz
    Nov 21 '18 at 1:48














0












0








0







// The way types defined:

interface SudoA {
foo: string;
}

interface SudoB {
bar: string;
}

type Sudo = SudoA | SudoB;

type SuperSudo = Sudo & {
super: boolean;
}

const baz: SuperSudo = {

}
// typescript (3.1.6) says i have to define both `bar` and `foo` for the object


What I expect is that to put super attribute and other attributes (coming from Sudo type) should be optional. The question; is this a wrong expectation? Regardless if yes or no how is this achieved?



Edit

Corrected the type of baz, my mistake :/.

What I am expecting is for SuperSudo defining only super attribute should be enough and other attributes coming from union of interfaces should be optional.



I can define a new type like
type SuperSudo<T> = T & {} but this ends up using SuperSudo<T>which I find quite verbose.



Edit2

Changed the title










share|improve this question















// The way types defined:

interface SudoA {
foo: string;
}

interface SudoB {
bar: string;
}

type Sudo = SudoA | SudoB;

type SuperSudo = Sudo & {
super: boolean;
}

const baz: SuperSudo = {

}
// typescript (3.1.6) says i have to define both `bar` and `foo` for the object


What I expect is that to put super attribute and other attributes (coming from Sudo type) should be optional. The question; is this a wrong expectation? Regardless if yes or no how is this achieved?



Edit

Corrected the type of baz, my mistake :/.

What I am expecting is for SuperSudo defining only super attribute should be enough and other attributes coming from union of interfaces should be optional.



I can define a new type like
type SuperSudo<T> = T & {} but this ends up using SuperSudo<T>which I find quite verbose.



Edit2

Changed the title







javascript typescript






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 '18 at 1:32

























asked Nov 21 '18 at 0:17









mdikici

4092617




4092617












  • I don't quite understand what you're saying. baz is in error because it needs to have at least one of the foo or bar properties in order to be SudoA | SudoB. And since baz is of type Sudo I don't understand how SuperSudo has anything to do with it. Could you rephrase the question or add more examples of what you expect to work and what you expect to report an error?
    – jcalz
    Nov 21 '18 at 0:43










  • When i understand your question, then you find the answer in the documentation of the release notes 2.8 typescript. typescriptlang.org/docs/handbook/release-notes/… Here is everything covered what you need to know about typings and how to make attributes optional / readonly / modify datatypes in inheritance.
    – Sly321
    Nov 21 '18 at 0:59






  • 1




    You want SuperSudo to only require super and not require any of the properties from SudoA or SudoB? What if SudoA has two or more properties (e.g., {foo: string, qux: number})? Can a SuperSudo contain just one of those properties (e.g., {super: true, foo: "a"})? It's still not clear to me what you're trying to do. Maybe you're looking for something like type AllKeys<T> = T extends any ? keyof T : never; type SuperSudo = {[K in AllKeys<Sudo>]?: Extract<Sudo, Record<K, any>>[K]} & {super: boolean;} but it's hard to be sure.
    – jcalz
    Nov 21 '18 at 1:48


















  • I don't quite understand what you're saying. baz is in error because it needs to have at least one of the foo or bar properties in order to be SudoA | SudoB. And since baz is of type Sudo I don't understand how SuperSudo has anything to do with it. Could you rephrase the question or add more examples of what you expect to work and what you expect to report an error?
    – jcalz
    Nov 21 '18 at 0:43










  • When i understand your question, then you find the answer in the documentation of the release notes 2.8 typescript. typescriptlang.org/docs/handbook/release-notes/… Here is everything covered what you need to know about typings and how to make attributes optional / readonly / modify datatypes in inheritance.
    – Sly321
    Nov 21 '18 at 0:59






  • 1




    You want SuperSudo to only require super and not require any of the properties from SudoA or SudoB? What if SudoA has two or more properties (e.g., {foo: string, qux: number})? Can a SuperSudo contain just one of those properties (e.g., {super: true, foo: "a"})? It's still not clear to me what you're trying to do. Maybe you're looking for something like type AllKeys<T> = T extends any ? keyof T : never; type SuperSudo = {[K in AllKeys<Sudo>]?: Extract<Sudo, Record<K, any>>[K]} & {super: boolean;} but it's hard to be sure.
    – jcalz
    Nov 21 '18 at 1:48
















I don't quite understand what you're saying. baz is in error because it needs to have at least one of the foo or bar properties in order to be SudoA | SudoB. And since baz is of type Sudo I don't understand how SuperSudo has anything to do with it. Could you rephrase the question or add more examples of what you expect to work and what you expect to report an error?
– jcalz
Nov 21 '18 at 0:43




I don't quite understand what you're saying. baz is in error because it needs to have at least one of the foo or bar properties in order to be SudoA | SudoB. And since baz is of type Sudo I don't understand how SuperSudo has anything to do with it. Could you rephrase the question or add more examples of what you expect to work and what you expect to report an error?
– jcalz
Nov 21 '18 at 0:43












When i understand your question, then you find the answer in the documentation of the release notes 2.8 typescript. typescriptlang.org/docs/handbook/release-notes/… Here is everything covered what you need to know about typings and how to make attributes optional / readonly / modify datatypes in inheritance.
– Sly321
Nov 21 '18 at 0:59




When i understand your question, then you find the answer in the documentation of the release notes 2.8 typescript. typescriptlang.org/docs/handbook/release-notes/… Here is everything covered what you need to know about typings and how to make attributes optional / readonly / modify datatypes in inheritance.
– Sly321
Nov 21 '18 at 0:59




1




1




You want SuperSudo to only require super and not require any of the properties from SudoA or SudoB? What if SudoA has two or more properties (e.g., {foo: string, qux: number})? Can a SuperSudo contain just one of those properties (e.g., {super: true, foo: "a"})? It's still not clear to me what you're trying to do. Maybe you're looking for something like type AllKeys<T> = T extends any ? keyof T : never; type SuperSudo = {[K in AllKeys<Sudo>]?: Extract<Sudo, Record<K, any>>[K]} & {super: boolean;} but it's hard to be sure.
– jcalz
Nov 21 '18 at 1:48




You want SuperSudo to only require super and not require any of the properties from SudoA or SudoB? What if SudoA has two or more properties (e.g., {foo: string, qux: number})? Can a SuperSudo contain just one of those properties (e.g., {super: true, foo: "a"})? It's still not clear to me what you're trying to do. Maybe you're looking for something like type AllKeys<T> = T extends any ? keyof T : never; type SuperSudo = {[K in AllKeys<Sudo>]?: Extract<Sudo, Record<K, any>>[K]} & {super: boolean;} but it's hard to be sure.
– jcalz
Nov 21 '18 at 1:48












1 Answer
1






active

oldest

votes


















0














Have you considered using a type discriminator?



Without one, then specifying either foo, bar or both foo and bar will always satisfy the union type.



With one might look like:



interface SudoA {
_type: "a";
foo: string;
}

interface SudoB {
_type: "b";
bar: string;
}

type Sudo = SudoA | SudoB;

type SuperSudo = Sudo & {
super: boolean;
}

const baz1_valid: SuperSudo = {
_type: "a",
super: true,
foo: "bar",
}

const baz2_valid: SuperSudo = {
_type: "b",
super: true,
bar: "foo",
}


The field name does not have to be _type, it simply must be the same field name with different type values on each variant.






share|improve this answer





















    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',
    autoActivateHeartbeat: false,
    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%2f53403550%2fway-to-define-a-type-in-typescript-like-one-of-union-of-interfaces-atrrib%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









    0














    Have you considered using a type discriminator?



    Without one, then specifying either foo, bar or both foo and bar will always satisfy the union type.



    With one might look like:



    interface SudoA {
    _type: "a";
    foo: string;
    }

    interface SudoB {
    _type: "b";
    bar: string;
    }

    type Sudo = SudoA | SudoB;

    type SuperSudo = Sudo & {
    super: boolean;
    }

    const baz1_valid: SuperSudo = {
    _type: "a",
    super: true,
    foo: "bar",
    }

    const baz2_valid: SuperSudo = {
    _type: "b",
    super: true,
    bar: "foo",
    }


    The field name does not have to be _type, it simply must be the same field name with different type values on each variant.






    share|improve this answer


























      0














      Have you considered using a type discriminator?



      Without one, then specifying either foo, bar or both foo and bar will always satisfy the union type.



      With one might look like:



      interface SudoA {
      _type: "a";
      foo: string;
      }

      interface SudoB {
      _type: "b";
      bar: string;
      }

      type Sudo = SudoA | SudoB;

      type SuperSudo = Sudo & {
      super: boolean;
      }

      const baz1_valid: SuperSudo = {
      _type: "a",
      super: true,
      foo: "bar",
      }

      const baz2_valid: SuperSudo = {
      _type: "b",
      super: true,
      bar: "foo",
      }


      The field name does not have to be _type, it simply must be the same field name with different type values on each variant.






      share|improve this answer
























        0












        0








        0






        Have you considered using a type discriminator?



        Without one, then specifying either foo, bar or both foo and bar will always satisfy the union type.



        With one might look like:



        interface SudoA {
        _type: "a";
        foo: string;
        }

        interface SudoB {
        _type: "b";
        bar: string;
        }

        type Sudo = SudoA | SudoB;

        type SuperSudo = Sudo & {
        super: boolean;
        }

        const baz1_valid: SuperSudo = {
        _type: "a",
        super: true,
        foo: "bar",
        }

        const baz2_valid: SuperSudo = {
        _type: "b",
        super: true,
        bar: "foo",
        }


        The field name does not have to be _type, it simply must be the same field name with different type values on each variant.






        share|improve this answer












        Have you considered using a type discriminator?



        Without one, then specifying either foo, bar or both foo and bar will always satisfy the union type.



        With one might look like:



        interface SudoA {
        _type: "a";
        foo: string;
        }

        interface SudoB {
        _type: "b";
        bar: string;
        }

        type Sudo = SudoA | SudoB;

        type SuperSudo = Sudo & {
        super: boolean;
        }

        const baz1_valid: SuperSudo = {
        _type: "a",
        super: true,
        foo: "bar",
        }

        const baz2_valid: SuperSudo = {
        _type: "b",
        super: true,
        bar: "foo",
        }


        The field name does not have to be _type, it simply must be the same field name with different type values on each variant.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 21 '18 at 4:49









        Alex

        1,9841415




        1,9841415






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53403550%2fway-to-define-a-type-in-typescript-like-one-of-union-of-interfaces-atrrib%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

            Costa Masnaga

            Fotorealismo

            Sidney Franklin