Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33462,10 +33462,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
error(errorNode, Diagnostics.Cannot_use_JSX_unless_the_jsx_flag_is_provided);
}

if (getJsxElementTypeAt(errorNode) === undefined) {
if (noImplicitAny) {
error(errorNode, Diagnostics.JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist);
}
if (noImplicitAny && isErrorType(getJsxElementTypeAt(errorNode))) {
error(errorNode, Diagnostics.JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist);
}
}

Expand Down
1 change: 1 addition & 0 deletions src/testRunner/unittests/tsc/incremental.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ declare global {
declare namespace JSX {
interface ElementChildrenAttribute { children: {}; }
interface IntrinsicElements { div: {} }
interface Element<P, T> { props: P; type: T; }
}

declare var React: any;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//// [checkJsxIntersectionElementPropsType.tsx]
declare namespace JSX {
interface ElementAttributesProperty { props: {}; }
interface Element<P, T> { props: P; type: T; }
}

declare class Component<P> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,46 @@ declare namespace JSX {
interface ElementAttributesProperty { props: {}; }
>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(checkJsxIntersectionElementPropsType.tsx, 0, 23))
>props : Symbol(ElementAttributesProperty.props, Decl(checkJsxIntersectionElementPropsType.tsx, 1, 41))

interface Element<P, T> { props: P; type: T; }
>Element : Symbol(Element, Decl(checkJsxIntersectionElementPropsType.tsx, 1, 54))
>P : Symbol(P, Decl(checkJsxIntersectionElementPropsType.tsx, 2, 22))
>T : Symbol(T, Decl(checkJsxIntersectionElementPropsType.tsx, 2, 24))
>props : Symbol(Element.props, Decl(checkJsxIntersectionElementPropsType.tsx, 2, 29))
>P : Symbol(P, Decl(checkJsxIntersectionElementPropsType.tsx, 2, 22))
>type : Symbol(Element.type, Decl(checkJsxIntersectionElementPropsType.tsx, 2, 39))
>T : Symbol(T, Decl(checkJsxIntersectionElementPropsType.tsx, 2, 24))
}

declare class Component<P> {
>Component : Symbol(Component, Decl(checkJsxIntersectionElementPropsType.tsx, 2, 1))
>P : Symbol(P, Decl(checkJsxIntersectionElementPropsType.tsx, 4, 24))
>Component : Symbol(Component, Decl(checkJsxIntersectionElementPropsType.tsx, 3, 1))
>P : Symbol(P, Decl(checkJsxIntersectionElementPropsType.tsx, 5, 24))

constructor(props: Readonly<P>);
>props : Symbol(props, Decl(checkJsxIntersectionElementPropsType.tsx, 5, 14))
>props : Symbol(props, Decl(checkJsxIntersectionElementPropsType.tsx, 6, 14))
>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --))
>P : Symbol(P, Decl(checkJsxIntersectionElementPropsType.tsx, 4, 24))
>P : Symbol(P, Decl(checkJsxIntersectionElementPropsType.tsx, 5, 24))

readonly props: Readonly<P>;
>props : Symbol(Component.props, Decl(checkJsxIntersectionElementPropsType.tsx, 5, 34))
>props : Symbol(Component.props, Decl(checkJsxIntersectionElementPropsType.tsx, 6, 34))
>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --))
>P : Symbol(P, Decl(checkJsxIntersectionElementPropsType.tsx, 4, 24))
>P : Symbol(P, Decl(checkJsxIntersectionElementPropsType.tsx, 5, 24))
}

class C<T> extends Component<{ x?: boolean; } & T> {}
>C : Symbol(C, Decl(checkJsxIntersectionElementPropsType.tsx, 7, 1))
>T : Symbol(T, Decl(checkJsxIntersectionElementPropsType.tsx, 9, 8))
>Component : Symbol(Component, Decl(checkJsxIntersectionElementPropsType.tsx, 2, 1))
>x : Symbol(x, Decl(checkJsxIntersectionElementPropsType.tsx, 9, 30))
>T : Symbol(T, Decl(checkJsxIntersectionElementPropsType.tsx, 9, 8))
>C : Symbol(C, Decl(checkJsxIntersectionElementPropsType.tsx, 8, 1))
>T : Symbol(T, Decl(checkJsxIntersectionElementPropsType.tsx, 10, 8))
>Component : Symbol(Component, Decl(checkJsxIntersectionElementPropsType.tsx, 3, 1))
>x : Symbol(x, Decl(checkJsxIntersectionElementPropsType.tsx, 10, 30))
>T : Symbol(T, Decl(checkJsxIntersectionElementPropsType.tsx, 10, 8))

const y = new C({foobar: "example"});
>y : Symbol(y, Decl(checkJsxIntersectionElementPropsType.tsx, 10, 5))
>C : Symbol(C, Decl(checkJsxIntersectionElementPropsType.tsx, 7, 1))
>foobar : Symbol(foobar, Decl(checkJsxIntersectionElementPropsType.tsx, 10, 17))
>y : Symbol(y, Decl(checkJsxIntersectionElementPropsType.tsx, 11, 5))
>C : Symbol(C, Decl(checkJsxIntersectionElementPropsType.tsx, 8, 1))
>foobar : Symbol(foobar, Decl(checkJsxIntersectionElementPropsType.tsx, 11, 17))

const x = <C foobar="example" />
>x : Symbol(x, Decl(checkJsxIntersectionElementPropsType.tsx, 11, 5))
>C : Symbol(C, Decl(checkJsxIntersectionElementPropsType.tsx, 7, 1))
>foobar : Symbol(foobar, Decl(checkJsxIntersectionElementPropsType.tsx, 11, 12))
>x : Symbol(x, Decl(checkJsxIntersectionElementPropsType.tsx, 12, 5))
>C : Symbol(C, Decl(checkJsxIntersectionElementPropsType.tsx, 8, 1))
>foobar : Symbol(foobar, Decl(checkJsxIntersectionElementPropsType.tsx, 12, 12))

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ declare namespace JSX {
interface ElementAttributesProperty { props: {}; }
>props : {}
> : ^^

interface Element<P, T> { props: P; type: T; }
>props : P
> : ^
>type : T
> : ^
}

declare class Component<P> {
Expand Down Expand Up @@ -43,8 +49,10 @@ const y = new C({foobar: "example"});
> : ^^^^^^^^^

const x = <C foobar="example" />
>x : error
><C foobar="example" /> : error
>x : JSX.Element<P, T>
> : ^^^^^^^^^^^^^^^^^
><C foobar="example" /> : JSX.Element<P, T>
> : ^^^^^^^^^^^^^^^^^
>C : typeof C
> : ^^^^^^^^
>foobar : string
Expand Down
4 changes: 4 additions & 0 deletions tests/baselines/reference/contextuallyTypedJsxAttribute.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
//// [tests/cases/compiler/contextuallyTypedJsxAttribute.ts] ////

//// [index.tsx]
declare namespace JSX {
interface Element<P, T> { props: P; type: T; }
}

interface Elements {
foo: { callback?: (value: number) => void };
bar: { callback?: (value: string) => void };
Expand Down
77 changes: 45 additions & 32 deletions tests/baselines/reference/contextuallyTypedJsxAttribute.symbols
Original file line number Diff line number Diff line change
@@ -1,70 +1,83 @@
//// [tests/cases/compiler/contextuallyTypedJsxAttribute.ts] ////

=== index.tsx ===
declare namespace JSX {
>JSX : Symbol(JSX, Decl(index.tsx, 0, 0))

interface Element<P, T> { props: P; type: T; }
>Element : Symbol(Element, Decl(index.tsx, 0, 23))
>P : Symbol(P, Decl(index.tsx, 1, 20))
>T : Symbol(T, Decl(index.tsx, 1, 22))
>props : Symbol(Element.props, Decl(index.tsx, 1, 27))
>P : Symbol(P, Decl(index.tsx, 1, 20))
>type : Symbol(Element.type, Decl(index.tsx, 1, 37))
>T : Symbol(T, Decl(index.tsx, 1, 22))
}

interface Elements {
>Elements : Symbol(Elements, Decl(index.tsx, 0, 0))
>Elements : Symbol(Elements, Decl(index.tsx, 2, 1))

foo: { callback?: (value: number) => void };
>foo : Symbol(Elements.foo, Decl(index.tsx, 0, 20))
>callback : Symbol(callback, Decl(index.tsx, 1, 8))
>value : Symbol(value, Decl(index.tsx, 1, 21))
>foo : Symbol(Elements.foo, Decl(index.tsx, 4, 20))
>callback : Symbol(callback, Decl(index.tsx, 5, 8))
>value : Symbol(value, Decl(index.tsx, 5, 21))

bar: { callback?: (value: string) => void };
>bar : Symbol(Elements.bar, Decl(index.tsx, 1, 46))
>callback : Symbol(callback, Decl(index.tsx, 2, 8))
>value : Symbol(value, Decl(index.tsx, 2, 21))
>bar : Symbol(Elements.bar, Decl(index.tsx, 5, 46))
>callback : Symbol(callback, Decl(index.tsx, 6, 8))
>value : Symbol(value, Decl(index.tsx, 6, 21))
}

type Props<C extends keyof Elements> = { as?: C } & Elements[C];
>Props : Symbol(Props, Decl(index.tsx, 3, 1))
>C : Symbol(C, Decl(index.tsx, 5, 11))
>Elements : Symbol(Elements, Decl(index.tsx, 0, 0))
>as : Symbol(as, Decl(index.tsx, 5, 40))
>C : Symbol(C, Decl(index.tsx, 5, 11))
>Elements : Symbol(Elements, Decl(index.tsx, 0, 0))
>C : Symbol(C, Decl(index.tsx, 5, 11))
>Props : Symbol(Props, Decl(index.tsx, 7, 1))
>C : Symbol(C, Decl(index.tsx, 9, 11))
>Elements : Symbol(Elements, Decl(index.tsx, 2, 1))
>as : Symbol(as, Decl(index.tsx, 9, 40))
>C : Symbol(C, Decl(index.tsx, 9, 11))
>Elements : Symbol(Elements, Decl(index.tsx, 2, 1))
>C : Symbol(C, Decl(index.tsx, 9, 11))

declare function Test<C extends keyof Elements>(props: Props<C>): null;
>Test : Symbol(Test, Decl(index.tsx, 5, 64))
>C : Symbol(C, Decl(index.tsx, 6, 22))
>Elements : Symbol(Elements, Decl(index.tsx, 0, 0))
>props : Symbol(props, Decl(index.tsx, 6, 48))
>Props : Symbol(Props, Decl(index.tsx, 3, 1))
>C : Symbol(C, Decl(index.tsx, 6, 22))
>Test : Symbol(Test, Decl(index.tsx, 9, 64))
>C : Symbol(C, Decl(index.tsx, 10, 22))
>Elements : Symbol(Elements, Decl(index.tsx, 2, 1))
>props : Symbol(props, Decl(index.tsx, 10, 48))
>Props : Symbol(Props, Decl(index.tsx, 7, 1))
>C : Symbol(C, Decl(index.tsx, 10, 22))

<Test
>Test : Symbol(Test, Decl(index.tsx, 5, 64))
>Test : Symbol(Test, Decl(index.tsx, 9, 64))

as="bar"
>as : Symbol(as, Decl(index.tsx, 8, 5))
>as : Symbol(as, Decl(index.tsx, 12, 5))

callback={(value) => {}}
>callback : Symbol(callback, Decl(index.tsx, 9, 10))
>value : Symbol(value, Decl(index.tsx, 10, 13))
>callback : Symbol(callback, Decl(index.tsx, 13, 10))
>value : Symbol(value, Decl(index.tsx, 14, 13))

/>;

Test({
>Test : Symbol(Test, Decl(index.tsx, 5, 64))
>Test : Symbol(Test, Decl(index.tsx, 9, 64))

as: "bar",
>as : Symbol(as, Decl(index.tsx, 13, 6))
>as : Symbol(as, Decl(index.tsx, 17, 6))

callback: (value) => {},
>callback : Symbol(callback, Decl(index.tsx, 14, 12))
>value : Symbol(value, Decl(index.tsx, 15, 13))
>callback : Symbol(callback, Decl(index.tsx, 18, 12))
>value : Symbol(value, Decl(index.tsx, 19, 13))

});

<Test<'bar'>
>Test : Symbol(Test, Decl(index.tsx, 5, 64))
>Test : Symbol(Test, Decl(index.tsx, 9, 64))

as="bar"
>as : Symbol(as, Decl(index.tsx, 18, 12))
>as : Symbol(as, Decl(index.tsx, 22, 12))

callback={(value) => {}}
>callback : Symbol(callback, Decl(index.tsx, 19, 10))
>value : Symbol(value, Decl(index.tsx, 20, 13))
>callback : Symbol(callback, Decl(index.tsx, 23, 10))
>value : Symbol(value, Decl(index.tsx, 24, 13))

/>;

14 changes: 12 additions & 2 deletions tests/baselines/reference/contextuallyTypedJsxAttribute.types
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
//// [tests/cases/compiler/contextuallyTypedJsxAttribute.ts] ////

=== index.tsx ===
declare namespace JSX {
interface Element<P, T> { props: P; type: T; }
>props : P
> : ^
>type : T
> : ^
}

interface Elements {
foo: { callback?: (value: number) => void };
>foo : { callback?: (value: number) => void; }
Expand Down Expand Up @@ -32,7 +40,8 @@ declare function Test<C extends keyof Elements>(props: Props<C>): null;
> : ^^^^^^^^

<Test
><Test as="bar" callback={(value) => {}}/> : error
><Test as="bar" callback={(value) => {}}/> : JSX.Element<P, T>
> : ^^^^^^^^^^^^^^^^^
>Test : <C extends keyof Elements>(props: Props<C>) => null
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^

Expand Down Expand Up @@ -75,7 +84,8 @@ Test({
});

<Test<'bar'>
><Test<'bar'> as="bar" callback={(value) => {}}/> : error
><Test<'bar'> as="bar" callback={(value) => {}}/> : JSX.Element<P, T>
> : ^^^^^^^^^^^^^^^^^
>Test : <C extends keyof Elements>(props: Props<C>) => null
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^

Expand Down
47 changes: 46 additions & 1 deletion tests/baselines/reference/discriminatedUnionJsxElement.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
//// [discriminatedUnionJsxElement.tsx]
// Repro from #46021

declare namespace JSX {
interface Element<P, T> { props: P; type: T; }
}

interface IData<MenuItemVariant extends ListItemVariant = ListItemVariant.OneLine> {
menuItemsVariant?: MenuItemVariant;
}
Expand Down Expand Up @@ -43,10 +47,16 @@ function ListItem(_data) {


//// [discriminatedUnionJsxElement.d.ts]
declare namespace JSX {
interface Element<P, T> {
props: P;
type: T;
}
}
interface IData<MenuItemVariant extends ListItemVariant = ListItemVariant.OneLine> {
menuItemsVariant?: MenuItemVariant;
}
declare function Menu<MenuItemVariant extends ListItemVariant = ListItemVariant.OneLine>(data: IData<MenuItemVariant>): any;
declare function Menu<MenuItemVariant extends ListItemVariant = ListItemVariant.OneLine>(data: IData<MenuItemVariant>): JSX.Element<P, T>;
type IListItemData = {
variant: ListItemVariant.Avatar;
} | {
Expand All @@ -57,3 +67,38 @@ declare enum ListItemVariant {
Avatar = 1
}
declare function ListItem(_data: IListItemData): null;


//// [DtsFileErrors]


discriminatedUnionJsxElement.d.ts(10,133): error TS2304: Cannot find name 'P'.
discriminatedUnionJsxElement.d.ts(10,136): error TS2304: Cannot find name 'T'.


==== discriminatedUnionJsxElement.d.ts (2 errors) ====
declare namespace JSX {
interface Element<P, T> {
props: P;
type: T;
}
}
interface IData<MenuItemVariant extends ListItemVariant = ListItemVariant.OneLine> {
menuItemsVariant?: MenuItemVariant;
}
declare function Menu<MenuItemVariant extends ListItemVariant = ListItemVariant.OneLine>(data: IData<MenuItemVariant>): JSX.Element<P, T>;
~
!!! error TS2304: Cannot find name 'P'.
~
!!! error TS2304: Cannot find name 'T'.
type IListItemData = {
variant: ListItemVariant.Avatar;
} | {
variant: ListItemVariant.OneLine;
};
declare enum ListItemVariant {
OneLine = 0,
Avatar = 1
}
declare function ListItem(_data: IListItemData): null;

Loading