Skip to content

Partial with #26272

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

Closed
jdforsythe opened this issue Aug 7, 2018 · 1 comment
Closed

Partial with #26272

jdforsythe opened this issue Aug 7, 2018 · 1 comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@jdforsythe
Copy link

TypeScript Version: 2.9.2

Search Terms: partial, spread, optional, required

Code

TS Playground

interface Foo {
  bar: string;
  name: string;
}

const common: Partial<Foo> = { bar: 'foobar' };
const foos: Foo[] = [
  { ...common, name: 'one' },
  { ...common, name: 'two' },
]; // error

const foosTwo: Foo[] = [
  { ...<Foo>common, name: 'one' },
  { ...<Foo>common, name: 'two' },
]; // type coercion works 

Expected behavior:

Typescript knows all the properties are provided and there are no errors

Actual behavior:

[ts]
Type '{ name: string; bar?: string; }[]' is not assignable to type 'Foo[]'.
  Type '{ name: string; bar?: string; }' is not assignable to type 'Foo'.
    Property 'bar' is optional in type '{ name: string; bar?: string; }' but required in type 'Foo'.

This error does not occur when assigning to a class property instead of a const:

TS Playground

class FooFactory {
  private foos: Foo[];

  constructor(foos) {
    this.foos = f;
  }
}

const common: Partial<Foo> = { bar: 'foobar' };

const fs = new FooFactory([
  { ...common, name: 'one' },
  { ...common, name: 'two' },
]); // no error

Playground Link:

Related Issues:

@RyanCavanaugh RyanCavanaugh added the Working as Intended The behavior described is the intended behavior; this is not a bug label Aug 7, 2018
@RyanCavanaugh
Copy link
Member

const common: Partial<Foo> = { bar: 'foobar' };
            ~~~~~~~~~~~~~~

When you write a type annotation for a variable declaration, TypeScript validates that the initializer conforms to that type, but otherwise discards information about the initializer. So we later here:

const foos: Foo[] = [
  { ...common, name: 'one' },
  { ...common, name: 'two' },
]; // error

TS doesn't know that you didn't specify name and not bar in common.

You can simply remove that type information to make the error go away.

In the class example, the constructor takes a parameter of type any so naturally there is no error.

See #26064 for discussion of syntax that would allow simultaneous in-place type validation without losing inference information from the initializer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

2 participants