Repository navigation
String literal types in complex type expressions #7199
Description
Activity
I could do
var fooBar:FooBar = mix({ ok:"ok", okToo: 42, notOk:"k" }) as FooBar ;
but then I loose all the benefits of type checking...
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>({ ... })var foo: Foo = { ok:"ok", okToo: 42, notOk:"k" }; var fooBar = mix(foo);
Should work fine. TS only infers literal types when there is a type annotation implying them.
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'.sandersn commented
on Feb 23, 2016 MemberMore actionsThe 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:var foobar: 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
stringas needed. After that goes in, the type of "k" will be "k" by default.- addedBugA bug in TypeScriptA bug in TypeScriptDomain: Error MessagesThe issue relates to error messagingThe issue relates to error messaging
on 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:type OK = "o" | "k"; interface Foo { //... nowOk: OK; } var foobar: FooBar = mix({ //... nowOk: "k" as OK; });
that should work, or even specifying the type argument explicitlly:
var foobar: FooBar = mix<Foo>({ //... nowOk: "k"; });
- addedSuggestionAn idea for TypeScriptAn idea for TypeScriptIn DiscussionNot yet reached consensusNot yet reached consensusand removedBugA bug in TypeScriptA bug in TypeScript
on Feb 23, 2016 - removedDomain: Error MessagesThe issue relates to error messagingThe issue relates to error messaging
on Feb 23, 2016 - addedNeeds ProposalThis issue needs a plan that clarifies the finer details of how it could be implemented.This issue needs a plan that clarifies the finer details of how it could be implemented.Domain: Error MessagesThe issue relates to error messagingThe issue relates to error messagingBugA bug in TypeScriptA bug in TypeScriptand removedSuggestionAn idea for TypeScriptAn idea for TypeScriptIn DiscussionNot yet reached consensusNot yet reached consensusNeeds ProposalThis issue needs a plan that clarifies the finer details of how it could be implemented.This issue needs a plan that clarifies the finer details of how it could be implemented.
on Feb 23, 2016 - addedFixedA PR has been merged for this issueA PR has been merged for this issue
on Feb 25, 2016 - locked and limited conversation to collaborators
on Jun 19, 2018
TypeScript Version:
1.8.2
Code
Expected behavior:
The assignment to
fooBarshould be allowed.Actual behavior:
I get the totally confusing error:
The confusing part is that it complains about the first property (
ok) and not aboutnotOk.Looking at the error message it seems that the string literal type
notOk:"o"|"k"was converted tonotOk :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: