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

String literal not assignable to type of the same value, forcing me to cast #16259

Closed
atrauzzi opened this issue Jun 5, 2017 · 5 comments
Closed
Labels
Duplicate An existing issue was already created

Comments

@atrauzzi
Copy link

atrauzzi commented Jun 5, 2017

I'm not sure if this has been brought up already and I'm just not plugging in the right search terms, but I feel like the compiler is forcing me to do a possibly redundant type annotation with string literal types.

TypeScript Version: 2.3.3

export interface AddAuthor extends Action {

    type: "add-author";

    author: Author;
}
export interface BusReducer<ActionType extends Action, State = any> {

    action: ActionType["type"];

    reducer(state: State, action: ActionType): State;
}
export class AddAuthor implements BusReducer<Action> {

    // tsc doesn't like this, failing with "Type 'string' is not assignable to type '"add-author"'."
    public action = "add-author";

    // But this seems to work...
    public action: "add-author" = "add-author";

    // ...
}

Expected behavior: Basically I expect that action in my BusReducer subtype not require its type be explicitly declared as the interface contains everything the lookup should need to successfully match on the constant value.

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Jun 5, 2017

Duplicate of #10570. I do appreciate that you tried to look it up. It wasn't easy for me to dig up either. 😄

@DanielRosenwasser DanielRosenwasser added the Duplicate An existing issue was already created label Jun 5, 2017
@typeofweb
Copy link

I have a very similar problem, although not related to implementing Interfaces, just to compatibility between string literal type and string literal values. See this very simple example:

const data = {
    myLiteral: 'yas'
};

type MyType = {
  myLiteral: 'yas' | 'nope';
};

function doSomething(productData: MyType): void {}

doSomething(data); // error Type 'string' is not assignable to type '"yas" | "nope"'.

https://www.typescriptlang.org/play/index.html#src=const%20data%20%3D%20%7B%0A%20%20%20%20myLiteral%3A%20'yas'%0A%7D%3B%0A%0Atype%20MyType%20%3D%20%7B%0A%20%20myLiteral%3A%20'yas'%20%7C%20'nope'%3B%0A%7D%3B%0A%0Afunction%20doSomething(productData%3A%20MyType)%3A%20void%20%7B%7D%0A%0AdoSomething(data)%3B%0A

@kitsonk
Copy link
Contributor

kitsonk commented Aug 8, 2017

const objects are not inferred to their literal type, because objects properties are mutable. The const only prevents re-assignment. There are slightly different rules when specifying an object literal as an argument, because it favours usability over strict typing. So while doSomething(data) throws, the following does not:

type MyType = {
  myLiteral: 'yas' | 'nope';
};

function doSomething(productData: MyType): void {}

doSomething({
  myLiteral: 'yas'
});

This is because TypeScript can easily statically determine that the myLiteral property won't be changing. Of course, data is easily assignable to MyType. This also works:

const data: MyType = {
    myLiteral: 'yas'
};

type MyType = {
  myLiteral: 'yas' | 'nope';
};

function doSomething(productData: MyType): void {}

doSomething(data);

These sort of general questions are better asked on StackOverflow or in Gitter.

@mhegazy
Copy link
Contributor

mhegazy commented Aug 22, 2017

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@mhegazy mhegazy closed this as completed Aug 22, 2017
@atrauzzi
Copy link
Author

Unfortunately the referenced duplicate seems to have gone dead. Any chance it can get attention?

@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

5 participants