Skip to content

TS allows wrong assignment #24448

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
Ailrun opened this issue May 29, 2018 · 4 comments
Closed

TS allows wrong assignment #24448

Ailrun opened this issue May 29, 2018 · 4 comments
Labels
Bug A bug in TypeScript
Milestone

Comments

@Ailrun
Copy link

Ailrun commented May 29, 2018

TypeScript Version: 2.8.1

Search Terms: Type checking, Intersection type, Interface, Optional properties

Code

// Following does not emit any errors (unexpected)
interface Base0 {
    k0: number;
}

type A = Base0
    & { k1?: { file: File, str: string } };

interface B extends Base0 {
    k1?: number;
}

declare const a: A;
const b: B = a;

// However, following emits an error (as expected)
type C =
    & { k1?: { file: File, str: string } };

interface D {
    k1?: number;
}

declare const c: C;
const d: D = c;

Expected behavior: Emits errors for const b: B = a and const d: D = c

Actual behavior: Emits an error only for const d: D = c

Playground Link: https://www.typescriptlang.org/play/index.html#src=%2F%2F%20Following%20does%20not%20emit%20any%20errors.%0D%0Ainterface%20Base0%20%7B%0D%0A%20%20%20%20k0%3A%20number%3B%0D%0A%7D%0D%0A%0D%0Atype%20A%20%3D%20Base0%0D%0A%20%20%20%20%26%20%7B%20k1%3F%3A%20%7B%20file%3A%20File%2C%20str%3A%20string%20%7D%20%7D%3B%0D%0A%0D%0Ainterface%20B%20extends%20Base0%20%7B%0D%0A%20%20%20%20k1%3F%3A%20number%3B%0D%0A%7D%0D%0A%0D%0Adeclare%20const%20a%3A%20A%3B%0D%0Aconst%20b%3A%20B%20%3D%20a%3B%0D%0A%0D%0A%2F%2F%20However%2C%20following%20emits%20an%20error.%0D%0Atype%20C%20%3D%0D%0A%20%20%20%20%26%20%7B%20k1%3F%3A%20%7B%20file%3A%20File%2C%20str%3A%20string%20%7D%20%7D%3B%0D%0A%0D%0Ainterface%20D%20%7B%0D%0A%20%20%20%20k1%3F%3A%20number%3B%0D%0A%7D%0D%0A%0D%0Adeclare%20const%20c%3A%20C%3B%0D%0Aconst%20d%3A%20D%20%3D%20c%3B%0D%0A

Related Issues:

@Ailrun Ailrun changed the title TS allows wrong assignment. TS allows wrong assignment May 29, 2018
@ghost
Copy link

ghost commented May 29, 2018

Simplified repro:

interface I {}
type A = I & { x?: string };
interface B { x?: number; }

declare const a: A;
const b: B = a;

@ghost ghost added the Bug A bug in TypeScript label May 29, 2018
@mhegazy mhegazy added this to the Future milestone Jul 21, 2018
@sandersn sandersn removed their assignment Jan 7, 2020
@mike-marcacci
Copy link

mike-marcacci commented May 8, 2020

This is especially easy to hit when the refinement occurs across function boundaries. This is a minimal reproduction in the form of a real-world case:

type A = {
  a?: string
}

type B = {
  b?: number
}

type AB = A & B;

function takesAB(arg: AB) {
  return arg.a && arg.b ? arg.a.repeat(arg.b) : ""
}

function takesB(arg: B) {
  return takesAB(arg)
}

const is_B_but_not_A = {
  a: true,
  b: 10
}

takesB(is_B_but_not_A)

While this issue specifically addresses the case where a property is optional, it is related to the secondary issue described here that effects objects with index signatures.

I might recommend that the title of this issue be refined to be a big more descriptive, perhaps something like "Optional properties can be assigned the wrong type"

@RyanCavanaugh
Copy link
Member

The case in the OP is now correctly an error in 3.9

@Ailrun
Copy link
Author

Ailrun commented May 12, 2020

Great, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

No branches or pull requests

5 participants