Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better inline type annotations #13208

Closed
johnfn opened this issue Dec 29, 2016 · 6 comments
Closed

Better inline type annotations #13208

johnfn opened this issue Dec 29, 2016 · 6 comments
Labels
Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript

Comments

@johnfn
Copy link

johnfn commented Dec 29, 2016

Say I'm writing some code like this:

type MyKeyValues = "a" | "b" | "c" | "d";
const myNestedObject = {
    foo: {
        "a": 1,
        "b": 2,
        "c": 3,
    },
    bar: 5,
    baz: 6
};

I would like myNestedObject to understand that foo is type { [key in MyKeyValues]: number }, so that the type of myNestedObject is fully inferred. I currently have a few suboptimal solutions:

  1. Duplicate the entire structure of myNestedObject like so:
    const myNestedObject: {
        foo: { [key in MyKeyValues]: number },
        bar: number,
        baz: number
    } = {
        foo: {
            "a": 1,
            "b": 2,
            "c": 3,
        },
        bar: 5,
        baz: 6
    };

I don't like this because it is a violation of DRY. If I want to add new keys to myNestedObject, I have to add them twice.

  1. Inline type conversion
    const myNestedObject = {
        foo: {
            "a": 1,
            "b": 2,
            "c": 3,
        } as  { [key in MyKeyValues]: number },
        bar: 5,
        baz: 6
    };

This is nicer on the eyes, but not nicer on the type checker. Now we don't get any error that "d" has been omitted from foo.

Summary: I would like some of syntax to give a type to the inner object.

@johnfn
Copy link
Author

johnfn commented Dec 29, 2016

To me, the obvious solution seems to give an error on { "a": 1, "b": 2, "c": 3 } as { [key in MyKeyValues]: number } because the object literal does not satisfy the type.

(But it seems like every time I propose what I believe is the obvious solution around here, someone tells me why it's horribly wrong, so I leave this as a separate comment to not distract from the main proposal 😉 )

@DanielRosenwasser DanielRosenwasser added Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript labels Dec 29, 2016
@normalser
Copy link

normalser commented Dec 29, 2016

Something similar in here: #7481 (comment) and #11216

@aluanhaddad
Copy link
Contributor

I really like @wallverb's suggestion. Also it would not limit this to mapped types.

@zpdDG4gta8XKpMCd
Copy link

also consider #13082 (automated extracting an interface from an object literal)

@aluanhaddad
Copy link
Contributor

@Aleksey-Bykov #13082 is a great but they serve different purposes. Both would be valuable.

@RyanCavanaugh
Copy link
Member

I think #7481 is the preferred answer here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

6 participants