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

Unable to assert(implicit down cast) narrow types from intersection types with partial object types #7531

Closed
falsandtru opened this issue Mar 16, 2016 · 5 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@falsandtru
Copy link
Contributor

TypeScript Version:

master

Code

<{a: number, b: number}>{a: <number&string>0, b: 0}; // ok
<{a: number, b: number}>{a: <number>0}; // ok
<{a: number, b: number}>{a: <number&string>0}; // error, should be able to assert

Expected behavior:

$ node built/local/tsc.js index.ts

Actual behavior:

$ node built/local/tsc.js index.ts
index.ts(3,1): error TS2352: Neither type '{ a: number & string; }' nor type '{ a: number; b: number; }' is assignable to the other.
  Property 'b' is missing in type '{ a: number & string; }'.
@mhegazy
Copy link
Contributor

mhegazy commented Mar 16, 2016

Do not really know how better to explain it than the error message does :)

Neither type '{ a: number & string; }' nor type '{ a: number; b: number; }' is assignable to the other.

@mhegazy mhegazy added the Question An issue which isn't directly actionable in code label Mar 16, 2016
@RyanCavanaugh
Copy link
Member

We have the rule in type assertions that your assertion has to be plausibly correct.

In other words, you can't write this code

var x = 'hello';
var y = <number>x; // Nope

because there's really no way that's true unless you've been telling some big lies about the type of something.

So in this case, if you want this to be legal (as a suggested change, not a bug), we'd need to see some rule which a) makes this legal, b) has some compelling justification as for why it should be legal, and c) doesn't allow any random type to be asserted to any other random type.

@falsandtru
Copy link
Contributor Author

TypeScript implicitly destructs intersection types in declarations.

var x: number & string;
var y: number = x;

Why TypeScript does not have the same rule in partial object?

@RyanCavanaugh
Copy link
Member

There's no implicit destructuring there, just a simple rule of assignability.

A simpler case to think about would be something like

interface Farm1 {
  x: Horse;
  y: Animal;
}
interface Farm2 {
  x: Animal;
  y: Dog;
}

var f1: Farm1;
var f2: Farm2;

f1 = <Farm1>f2;

This assertion isn't allowed because neither Farm1 nor Farm2 is assignable to the other. You can't have one property go "up" while the other goes "down" -- either all the properties are being asserted to a supertype, or all the properties are asserted to a subtype. There's no mixing and matching allowed.

#5300 is closely related.

@falsandtru
Copy link
Contributor Author

I understood that. Thanks @RyanCavanaugh .

@RyanCavanaugh RyanCavanaugh marked this as a duplicate of #17338 Jul 21, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

3 participants