Skip to content

Typescript: Payload type is unknown when all properties of payload are optional #995

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

Closed
bmakan opened this issue Apr 12, 2021 · 7 comments
Closed

Comments

@bmakan
Copy link

bmakan commented Apr 12, 2021

Possibly related to: #214

When all properties of a payload are optional, the payload becomes unknown.

const action = createAction<{
    one: any,
    two?: any,
}>('ACTION');
type R = ReturnType<typeof action>;

// Becomes...
type R = {
    payload: {
        one: any;
        two?: any;
    };
    type: string;
}
const action = createAction<{
    one?: any,
    two?: any,
}>('ACTION');
type R = ReturnType<typeof action>;

// Becomes...
type R = {
    payload: unknown;
    type: string;
}

// Should be
type R = {
    payload: {
        one?: any;
        two?: any;
    };
    type: string;
}

Same goes for actions made with reducers property of the createSlice when using PayloadAction<T>.

Versions:

{
    "@reduxjs/toolkit": "^1.5.1",
    "@types/react-redux": "^7.1.16",
    "typescript": "^4.2.3",
}
@phryneas
Copy link
Member

I can't really reproduce that in this TS playground - could you try to reproduce it there?

(Note: your "// Becomes..." annotations override the real R, so make sure not to paste these over)

@bmakan
Copy link
Author

bmakan commented Apr 12, 2021

I can confirm it's working in the playground, but not in the VS Code. I even created a clean project with only @reduxjs/toolkit in it.

Could it be a VS Code issue then? As soon as I switch one of the properties to required, the intellisense and validation work correctly.

@phryneas
Copy link
Member

Personally I would think more that your tsconfig might play a role there. Can you reproduce your tsconfig settings in the playground?

If it's something with strict: false we can't really support that though, as that adds toooo many additional edge cases to everything ☹️

@bmakan
Copy link
Author

bmakan commented Apr 12, 2021

I didn't have a tsconfig when I tried it in a fresh project.
Otherwise, this is what I use:

{
    "compilerOptions": {
        "allowJs": true,
        "baseUrl": ".",
        "esModuleInterop" : true,
        "jsx": "react",
        "module": "es6",
        "moduleResolution": "Node",
        "noImplicitAny": true,
        // This is not used with ts-loader
        "outDir": "../../dist/",
        "paths": {
            ...
        },
        "sourceMap": true,
        "target": "es5"
    }
}

@phryneas
Copy link
Member

Does adding a strict: true resolve the issue?

@bmakan
Copy link
Author

bmakan commented Apr 12, 2021

Yes, it does. I didn't know there's a strict mode at all.
Might be worth mentioning in the docs it is recommended or even required to use it, otherwise some features may not function properly.

Anyway, my issue is solved and I am happy again. Feel free to close as far as I'm concerned. Thank you for the assistance.

@phryneas
Copy link
Member

phryneas commented Apr 12, 2021

Yeah, that's one of those TypeScript ecosystem problems.

Using tsc --init gives you a strict: true while some projects give you files without it to "ease the use" (or because they're badly written and won't work otherwise).

Point is: without strict, you're not really using TypeScript, but just a very small featureset.
Stuff like const x: string = null are suddenly possible.

And every function call is so ambiguous that it's not really valid for us to make any assumption any more :/

But yeah, we should probably add a disclaimer somewhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants