You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
String literal types in complex type expressions #7199
Error:(20, 5) TS2322: Type '{ ok: string; notOk: string; } & Bar' is not assignable to type 'FooBar'.
Type 'Bar' is not assignable to type 'FooBar'.
Property 'ok' is missing in type 'Bar'.
The confusing part is that it complains about the first property (ok) and not about notOk.
Looking at the error message it seems that the string literal type notOk:"o"|"k" was converted to notOk :string.
Therefore when I turn the string literal type to a string (notOk:string) everything is OK....
Hint: defining the string literal type as a type does not solve the problem:
I think you're expecting too much from type argument inference. Give mix an explicit type argument and it should work: var fooBar: FooBar = mix<Foo>({ ... })
It is as Wesley Wigham (@weswigham) explained. Though we may be should consider give a better error message especially this part of the error is a bit misleading
Type 'Bar' is not assignable to type 'FooBar'.
Property 'ok' is missing in type 'Bar'.
The problem is that, in the object literal passed to mix, notOk is inferred to be string absent any other information. As soon as the compiler knows that notOk: "k" is actually of type "k" or "o" | "k" then the assignment works. The minimal annotation is actually:
varfoobar: FooBar=mix({ok:"ok",okToo: 42,notOk: "k"as"k"// or as "o" | "k"});
The error message you get without the annotation looks completely wrong to me, or at least misleading.
Daniel Rosenwasser (@DanielRosenwasser) has a PR #6554 that defaults string literals to string literal types, and then widens to string as needed. After that goes in, the type of "k" will be "k" by default.
Activity
scharf commentedon Feb 23, 2016
I could do
but then I loose all the benefits of type checking...
jeffreymorlan commentedon Feb 23, 2016
I think you're expecting too much from type argument inference. Give
mixan explicit type argument and it should work:var fooBar: FooBar = mix<Foo>({ ... })weswigham commentedon Feb 23, 2016
Should work fine. TS only infers literal types when there is a type annotation implying them.
yuit commentedon Feb 23, 2016
It is as Wesley Wigham (@weswigham) explained. Though we may be should consider give a better error message especially this part of the error is a bit misleading
sandersn commentedon Feb 23, 2016
The problem is that, in the object literal passed to
mix,notOkis inferred to be string absent any other information. As soon as the compiler knows thatnotOk: "k"is actually of type"k"or"o" | "k"then the assignment works. The minimal annotation is actually:The error message you get without the annotation looks completely wrong to me, or at least misleading.
Daniel Rosenwasser (@DanielRosenwasser) has a PR #6554 that defaults string literals to string literal types, and then widens to
stringas needed. After that goes in, the type of "k" will be "k" by default.scharf commentedon Feb 23, 2016
Nathan Shively-Sanders (@sandersn) that solves the problem :-)
So, if I define
type OK = "o" | "k";I can use it in the cast:mhegazy commentedon Feb 23, 2016
that should work, or even specifying the type argument explicitlly: