Skip to content

String literals not contextually typed within jsx attributes #19041

@weswigham

Description

@weswigham
Member

Found while working on #18670 while looking over changes to contextuallyTypedStringLiteralsInJsxAttributes02. Comments in the file indicate that the goTo parameter of MainButton is supposed to be contextually typed as a literal type instead of string, but upon inspecting the type baselines you can see that it is always just string... this doesn't surface in the error baseline, since the test is simultaneously looking at excess property errors.

Activity

added this to the TypeScript 2.7 milestone on Oct 9, 2017
weswigham

weswigham commented on Dec 14, 2017

@weswigham
MemberAuthor

This is just a quirk of how getTypeAtLocation works, and applies to both object literals and JSX.

For example, in:

// @jsx: preserve

namespace JSX {
    export interface IntrinsicElements {
        span: {};
    }
    export interface Element {
		something?: any;
    }
}

const Foo = (props: { foo: "A" | "B" | "C" }) => <span>{props.foo}</span>;

Foo({
    foo: "B"
});

<Foo foo="B" />

In both calls to Foo, the property foo has its type baseline printed as string - the widened type of the initializer - despite that not being the contextual type (which is "A" | "B" | "C") or the inferred type for that member of the object (which is "B"). The top-level object type is built correctly, since it doesn't use getTypeOfSymbol - it uses checkPropertyAssignment on each property, which defers to checkExpressionForMutableLocation instead. It looks like using getWidenedTypeForVariableLikeDeclaration outside of checkVariableLikeDeclaration is highly suspect (since it is being expected to handle more kinds than it does). This disproportionately affects JSX baselines, since they have no top-level JsxAttributes object type baselines to inspect for correctness and more frequently have literal-typed properties (at least in our own baselines).

This is probably worth fixing, if only to make life easier for our API consumers and our type baselines actually correct, but should also make quick info accurate on JSX attributes (property assignments are already accurate, so they're likely using a special secondary code path somewhere...). Fixing this has also exposed how we don't handle literal widening on jsx attributes correctly (or at all).

added
FixedA PR has been merged for this issue
on Jan 9, 2018
locked and limited conversation to collaborators on Jul 3, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptFixedA PR has been merged for this issue

Type

No type

Projects

No projects

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @weswigham@mhegazy

      Issue actions

        String literals not contextually typed within jsx attributes · Issue #19041 · microsoft/TypeScript