diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c6260a958dea3..f93a60b9281ef 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12034,8 +12034,8 @@ namespace ts { } if (target.flags & TypeFlags.TypeParameter) { - // A source type { [P in keyof T]: X } is related to a target type T if X is related to T[P]. - if (getObjectFlags(source) & ObjectFlags.Mapped && getConstraintTypeFromMappedType(source) === getIndexType(target)) { + // A source type { [P in Q]: X } is related to a target type T if keyof T is related to Q and X is related to T[Q]. + if (getObjectFlags(source) & ObjectFlags.Mapped && isRelatedTo(getIndexType(target), getConstraintTypeFromMappedType(source))) { if (!(getMappedTypeModifiers(source) & MappedTypeModifiers.IncludeOptional)) { const templateType = getTemplateTypeFromMappedType(source); const indexedAccessType = getIndexedAccessType(target, getTypeParameterFromMappedType(source)); @@ -12089,7 +12089,7 @@ namespace ts { (template).indexType === getTypeParameterFromMappedType(target)) { return Ternary.True; } - // A source type T is related to a target type { [P in keyof T]: X } if T[P] is related to X. + // A source type T is related to a target type { [P in Q]: X } if Q is related to keyof T and T[Q] is related to X. if (!isGenericMappedType(source) && isRelatedTo(getConstraintTypeFromMappedType(target), getIndexType(source))) { const indexedAccessType = getIndexedAccessType(source, getTypeParameterFromMappedType(target)); const templateType = getTemplateTypeFromMappedType(target); diff --git a/tests/baselines/reference/reactHOCSpreadprops.js b/tests/baselines/reference/reactHOCSpreadprops.js new file mode 100644 index 0000000000000..45ecbe35f6829 --- /dev/null +++ b/tests/baselines/reference/reactHOCSpreadprops.js @@ -0,0 +1,53 @@ +//// [reactHOCSpreadprops.tsx] +/// +import React = require("react"); +function f

(App: React.ComponentClass

| React.StatelessComponent

): void { + class C extends React.Component

{ + render() { + return ; + } + } +} + + +//// [reactHOCSpreadprops.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +exports.__esModule = true; +/// +var React = require("react"); +function f(App) { + var C = /** @class */ (function (_super) { + __extends(C, _super); + function C() { + return _super !== null && _super.apply(this, arguments) || this; + } + C.prototype.render = function () { + return React.createElement(App, __assign({}, this.props)); + }; + return C; + }(React.Component)); +} diff --git a/tests/baselines/reference/reactHOCSpreadprops.symbols b/tests/baselines/reference/reactHOCSpreadprops.symbols new file mode 100644 index 0000000000000..06e698014f4ab --- /dev/null +++ b/tests/baselines/reference/reactHOCSpreadprops.symbols @@ -0,0 +1,36 @@ +=== tests/cases/compiler/reactHOCSpreadprops.tsx === +/// +import React = require("react"); +>React : Symbol(React, Decl(reactHOCSpreadprops.tsx, 0, 0)) + +function f

(App: React.ComponentClass

| React.StatelessComponent

): void { +>f : Symbol(f, Decl(reactHOCSpreadprops.tsx, 1, 32)) +>P : Symbol(P, Decl(reactHOCSpreadprops.tsx, 2, 11)) +>App : Symbol(App, Decl(reactHOCSpreadprops.tsx, 2, 14)) +>React : Symbol(React, Decl(reactHOCSpreadprops.tsx, 0, 0)) +>ComponentClass : Symbol(React.ComponentClass, Decl(react16.d.ts, 421, 9)) +>P : Symbol(P, Decl(reactHOCSpreadprops.tsx, 2, 11)) +>React : Symbol(React, Decl(reactHOCSpreadprops.tsx, 0, 0)) +>StatelessComponent : Symbol(React.StatelessComponent, Decl(react16.d.ts, 406, 49)) +>P : Symbol(P, Decl(reactHOCSpreadprops.tsx, 2, 11)) + + class C extends React.Component

{ +>C : Symbol(C, Decl(reactHOCSpreadprops.tsx, 2, 81)) +>React.Component : Symbol(React.Component, Decl(react16.d.ts, 345, 54), Decl(react16.d.ts, 349, 94)) +>React : Symbol(React, Decl(reactHOCSpreadprops.tsx, 0, 0)) +>Component : Symbol(React.Component, Decl(react16.d.ts, 345, 54), Decl(react16.d.ts, 349, 94)) +>P : Symbol(P, Decl(reactHOCSpreadprops.tsx, 2, 11)) +>x : Symbol(x, Decl(reactHOCSpreadprops.tsx, 3, 41)) + + render() { +>render : Symbol(C.render, Decl(reactHOCSpreadprops.tsx, 3, 56)) + + return ; +>App : Symbol(App, Decl(reactHOCSpreadprops.tsx, 2, 14)) +>this.props : Symbol(React.Component.props, Decl(react16.d.ts, 367, 32)) +>this : Symbol(C, Decl(reactHOCSpreadprops.tsx, 2, 81)) +>props : Symbol(React.Component.props, Decl(react16.d.ts, 367, 32)) + } + } +} + diff --git a/tests/baselines/reference/reactHOCSpreadprops.types b/tests/baselines/reference/reactHOCSpreadprops.types new file mode 100644 index 0000000000000..b343ea5fc7af3 --- /dev/null +++ b/tests/baselines/reference/reactHOCSpreadprops.types @@ -0,0 +1,31 @@ +=== tests/cases/compiler/reactHOCSpreadprops.tsx === +/// +import React = require("react"); +>React : typeof React + +function f

(App: React.ComponentClass

| React.StatelessComponent

): void { +>f :

(App: React.ComponentClass | React.StatelessComponent

) => void +>App : React.ComponentClass | React.StatelessComponent

+>React : any +>React : any + + class C extends React.Component

{ +>C : C +>React.Component : React.Component

+>React : typeof React +>Component : typeof React.Component +>x : number + + render() { +>render : () => JSX.Element + + return ; +> : JSX.Element +>App : React.ComponentClass | React.StatelessComponent

+>this.props : Readonly<{ children?: React.ReactNode; }> & Readonly

+>this : this +>props : Readonly<{ children?: React.ReactNode; }> & Readonly

+ } + } +} + diff --git a/tests/cases/compiler/reactHOCSpreadprops.tsx b/tests/cases/compiler/reactHOCSpreadprops.tsx new file mode 100644 index 0000000000000..3b1b3e747241b --- /dev/null +++ b/tests/cases/compiler/reactHOCSpreadprops.tsx @@ -0,0 +1,11 @@ +// @jsx: react +// @strict: true +/// +import React = require("react"); +function f

(App: React.ComponentClass

| React.StatelessComponent

): void { + class C extends React.Component

{ + render() { + return ; + } + } +}