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

TypeScript doesn't correctly typecheck React/JSX union properties #10171

Closed
gcnew opened this issue Aug 5, 2016 · 3 comments
Closed

TypeScript doesn't correctly typecheck React/JSX union properties #10171

gcnew opened this issue Aug 5, 2016 · 3 comments
Labels
Bug A bug in TypeScript Domain: JSX/TSX Relates to the JSX parser and emitter

Comments

@gcnew
Copy link
Contributor

gcnew commented Aug 5, 2016

TypeScript Version: nightly (2.1.0-dev.20160805)

Code

import * as React from "react";
import * as ReactDOM from "react-dom";

type TextProps = { editable: false }
               | { editable: true, onEdit: (newText: string) => void }

class TextComponent extends React.Component<TextProps, {}> {
    render() {
        return <span>Some Text..</span>;
    }
}

ReactDOM.render(
    <TextComponent editable={true} />, // FAIL: should be an error, but it's not
                                       // `onEdit` is missing
    document.getElementById("example")
);

// OK: correctly issues an error
React.createElement(TextComponent, { editable: true as true });

Unfortunately, not only is the parameter presence not enforced, but also it cannot be provided even if the programmer somehow notices:

ReactDOM.render(
    // Property 'onEdit' does not exist on type ...
    <TextComponent editable={true} onEdit={ () => {} } />,
    document.getElementById("example")
);

Type-safe workaround:

const textProps: TextProps = {
    editable: true as true,  // Whoops, why not literal type?
    onEdit: () => {}
};

ReactDOM.render(
    <TextComponent {...textProps} />,
    document.getElementById("example")
);

Expected behavior:
The compiler should check whether the provided property set in JSX syntax matches the expected one according to the normal typing rules.

PS: Is there a way to see the desugarred TS?

@DanielRosenwasser DanielRosenwasser added Bug A bug in TypeScript Domain: JSX/TSX Relates to the JSX parser and emitter Domain: Literal Types Unit types including string literal types, numeric literal types, Boolean literals, null, undefined labels Aug 5, 2016
@DanielRosenwasser DanielRosenwasser self-assigned this Aug 5, 2016
@DanielRosenwasser DanielRosenwasser added this to the TypeScript 2.0.1 milestone Aug 5, 2016
@DanielRosenwasser
Copy link
Member

true might not be getting contextually typed appropriately.

@DanielRosenwasser DanielRosenwasser removed their assignment Aug 5, 2016
@DanielRosenwasser DanielRosenwasser removed the Domain: Literal Types Unit types including string literal types, numeric literal types, Boolean literals, null, undefined label Aug 5, 2016
@DanielRosenwasser
Copy link
Member

Actually I don't think this is unique to discriminated unions or literal types.

@yuit yuit self-assigned this Aug 16, 2016
@yuit
Copy link
Contributor

yuit commented Aug 17, 2016

The reason this is allowed:

ReactDOM.render(
    <TextComponent editable={true} />, // FAIL: should be an error, but it's not
                                       // `onEdit` is missing
    document.getElementById("example")
);

is that editable has type boolean while below editable has literal type of true as you cast it so

// OK: correctly issues an error
React.createElement(TextComponent, { editable: true as true }); 

Talk with @RyanCavanaugh offline, we should treat JSX attribute/property as literal type. However, this will be quite a big change so I will push it into the next release of 2.1.

@yuit yuit modified the milestones: TypeScript 2.1, TypeScript 2.0.1 Aug 17, 2016
@yuit yuit closed this as completed Aug 17, 2016
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug A bug in TypeScript Domain: JSX/TSX Relates to the JSX parser and emitter
Projects
None yet
Development

No branches or pull requests

3 participants