question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Unsafe type-incompatible assignments should not be allowed

See original GitHub issue

TypeScript Version: 2.1.6

Code

interface StringOnly {
  val: string;
}

interface StringOrNull {
  val: string | null;
}

const obj: StringOnly = { val: "str" };

// should not be allowed
const nullable: StringOrNull = obj;

nullable.val = null;

// obj is now in a bad state

Expected behavior: The sample should not compile, as it’s not safe. Type casts/assertions should be required to override type incompatibility errors here. (Or, of course, cloning the object itself const nullable: StringOrNull = { ...str };).

For comparison, Flow does not allow the sample code.

Actual behavior: The sample compiles and further accesses of str.val will likely result in exceptions.

EDIT: Removed all references to readonly, as discussion of that modifier is overshadowing the issue.

Issue Analytics

  • State:open
  • Created 7 years ago
  • Reactions:12
  • Comments:25 (10 by maintainers)

github_iconTop GitHub Comments

2reactions
jaredrucommented, Feb 22, 2017

but now we are in the 🚲 🏡 zone.

Fair enough. 😄

Would it be reasonable to remove the “Duplicate” label and judge this on its own as a suggestion to add a --strictVarianceChecks flag? I understand that the suggestion may or may not gain any ground, but it would be nice to have it considered. (I’d be happy to open a new issue for that and simply close this, as well).

2reactions
jaredrucommented, Feb 22, 2017

As I said, please ignore readonly. This is not a duplicate.

The problem is fundamentally about allowing incompatible type assignments. This is a problem regardless of whether readonly existed in the language or not. Flow does not have readonly, and Flow does not allow these assignments. (I’m not suggesting TypeScript should blindly copy Flow; I’m pointing out that this is a safety problem they recognize and prevent).

I’m not suggesting that the value should be immutable, simply that allowing it to be assigned a number breaks the original reference’s type. It’s unsafe because we’re treating val as string and string | number after the second assignment. The exact same object is referenced by two variables of two different, incompatible types.

Here’s my example again, annotated further to explain the problem in more depth:

const a: { val: string } = { val: "str" };
// There is now one reference to the object.
// The object's type is `{ val: string }`.

const b: { val: string | number } = a;
// There are now two references to the **same** object.  We did not copy the
// object, we simply added another reference.
//
// However, our two references treat the object as different, incompatible
// types.  Flow does not have `readonly`, but Flow does not allow the previous
// assignment.

b.val = "a different string";
// This is OK.  The object being mutable is fine, so long as the types match.
// This does not break `a`.  `a` expects `val` to be a `string`, and it is.

console.log(a.val.toUpperCase());
// Yay, `a.val` is the type we expected, so this logs correctly.

b.val = 3;
// Since `b` references the same object as `a`, this breaks `a`.  The inner
// `val` is now a number, and not the expected `string`.

console.log(a.val.toUpperCase());
// This throws an Error, because `a.val` is no longer a `string` like the type
// specifies it should be.
Read more comments on GitHub >

github_iconTop Results From Across the Web

Typescript union type consistency - Stack Overflow
... GitHub issue about this: microsoft/TypeScript#14150, a suggestion that "unsafe type-incompatible assignments should not be allowed".
Read more >
Build failed in Jenkins: jdk9-checker-framework #200
java:471: warning: [assignment.type.incompatible] incompatible types in assignment. ... [exec] src/java/lang/Throwable.java:961: warning: [assignment.type.
Read more >
internal/apidiff - tools - Git at Google
Checking Go Package API Compatibility. The apidiff tool in this directory determines whether two versions of the same package are compatible.
Read more >
Resource Reservation Protocol (RSVP) Parameters
Information on RSVP Assignment and Modification Guidelines can be found ... 6, Routing adjacency creation not allowed by policy, [RFC6107].
Read more >
Remedy & ITSM Error Message Lookup - ARE|RRR - rrr.se
Level Number Subject NOTE 32 AR System server terminated normally. ARERR 49 Internal error: The request ID is invalid. WARNING 50 You have no permission to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found