Repository navigation
Erroneous error when assigning to string literal union type #11714
Description
Activity
Tom Crockett (@pelotom) This should be fixed by #10676 and I can't reproduce the error with the current nightly build. Can you confirm that you're seeing this problem with the nightly?
- addedNeeds More InfoThe issue still hasn't been fully clarifiedThe issue still hasn't been fully clarified
on Oct 18, 2016 Yes, I just tried with
typescript@nextand it appears to be fixed. Thanks!- addedFixedA PR has been merged for this issueA PR has been merged for this issueand removedNeeds More InfoThe issue still hasn't been fully clarifiedThe issue still hasn't been fully clarified
on Oct 19, 2016 I'm reopening this because I just found another very similar case which is still broken:
interface I { xOrY: 'x' | 'y' } class C implements I { xOrY = 'x' }
This produces the error:
Class 'C' incorrectly implements interface 'I'. Types of property 'xOrY' are incompatible. Type 'string' is not assignable to type '"x" | "y"'.Adding this seemingly superfluous type ascription fixes it:
class C implements I { xOrY = 'x' as 'x' | 'y' }
RyanCavanaugh commented
on Oct 19, 2016 MemberMore actionsTom Crockett (@pelotom) this error is correct. Because the field isn't
readonly, you could write code like this, which wouldn't be sound:interface I { xOrY: 'x' | 'y' } class C implements I { xOrY = 'x'; // note: xOrY of type 'string' } let c = new C(); c.xOrY = 'z'; fn(c); function fn(i: I) { if (i !== 'x' && i !== 'y') throw new Error('Inconceivable!'); }
Side note, correct inference for
readonlyfields is currently only in themasterbranchBut...
xOrYis not of typestring. The interface dictates that it must be of type'x' | 'y'.What I'm saying is that the inferred type of the field
C.xOrYshould be'x' | 'y', because it could not type check any other way if it is to adhere to the interfaceI.readonlydoesn't enter into it, because even in the case where it's notreadonly, ifxOrYis understood to have type'x' | 'y', you can't reassign something that doesn't conform:interface I { xOrY: 'x' | 'y' } const c: I = { xOrY: 'x' } c.xOrY = 'z' // ERROR: Type '"z"' is not assignable to type '"x" | "y"'.
RyanCavanaugh commented
on Oct 19, 2016 MemberMore actionsTom Crockett (@pelotom)
implementsclause does not contextually type class property declaration. this is a common issue we get. #10570 should be tracking this.this is a different issue from the OP though. closing in favor of #10570.
Ok, thanks for the pointer!
- locked and limited conversation to collaborators
on Jun 19, 2018
TypeScript Version: 2.0.3 / nightly (2.1.0-dev.201xxxxx)
Code
Expected behavior:
The code should type check.
Actual behavior:
The last line is flagged with an error:
It can be fixed by giving
xOrYa type annotation to say that it has type"x" | "y", but the compiler seems to have already inferred that it has this type (based on whatatom-typescript's show-types-on-hover feature is telling me), so that doesn't seem like it should be necessary.When the union is of non-string literal types, there is no such error.