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

ignore type of overwritten object spread properties? #6800

Closed
jedwards1211 opened this issue Aug 27, 2018 · 4 comments
Closed

ignore type of overwritten object spread properties? #6800

jedwards1211 opened this issue Aug 27, 2018 · 4 comments

Comments

@jedwards1211
Copy link
Contributor

The following function is guaranteed to set the name property to a defined value, but Flow complains about the ...input spread because its name property is optional. Maybe the type of name from ...input should be ignored since it is overwritten by the name in the object literal?

Code Try flow link

type Optional = {name?: ?string, foo: number}
type Required = {name: string, foo: number}

function normalize(input: Optional): Required {
  return {
    ...input,
    name: input.name || 'unnamed',
  }
}

Errors

5:   return {
            ^ Cannot return object literal because null or undefined [1] is incompatible with string [2] in property `name`.
References:
1: type Optional = {name?: ?string, foo: number}
                           ^ [1]
2: type Required = {name: string, foo: number}

Less performant workaround

The only type-safe workaround I can think of (using object rest spread or similar) incurs a performance penalty:

function normalize({name, ...input}: Optional): Required {
  return {
    ...input,
    name: name || 'unnamed',
  }
}
@ghost
Copy link

ghost commented Sep 1, 2018

type Optional = {name: ?string, foo: number}
type Required = {name: string, foo: number}

function normalize(input: Optional): Required {
  return (({
    ...input,
    name: input.name && 'unnamed',
  }:any):Required)
}

@jedwards1211
Copy link
Contributor Author

jedwards1211 commented Sep 1, 2018

@bhandarijiwan yes, that's a reasonable workaround, and I do things like that in all sorts of places... Using any is not truly type-safe in the sense that one could accidentally make mistakes in the type definitions of Optional and Required such that some props are not actually compatible, but Flow would have no way of knowing due to any usage. But oftentimes one still has to use any, and functions like that are the safest way to do it :)

@adimit
Copy link

adimit commented Oct 29, 2018

This is a duplicate of #6108.

@goodmind
Copy link
Contributor

Duplicate of #6108

@goodmind goodmind marked this as a duplicate of #6108 Apr 28, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants