mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-07-05 00:32:41 -05:00
Obey the excludeArgument parameter when checking JSX signature validity (#28002)
* Obey the excludeArgument parameter when checking JSX signature validity * Fix conditional type extending any contextual types and accept baselines * use flag check to also drop unknown from comparison for the same reason * Slight refinement - make an intersection to ensure parameter constraints flow through contextual types when instantiated * Format ternary more nicely
This commit is contained in:
@@ -7083,7 +7083,11 @@ namespace ts {
|
||||
function getDefaultConstraintOfConditionalType(type: ConditionalType) {
|
||||
if (!type.resolvedDefaultConstraint) {
|
||||
const rootTrueType = type.root.trueType;
|
||||
const rootTrueConstraint = rootTrueType.flags & TypeFlags.Substitution ? (<SubstitutionType>rootTrueType).substitute : rootTrueType;
|
||||
const rootTrueConstraint = !(rootTrueType.flags & TypeFlags.Substitution)
|
||||
? rootTrueType
|
||||
: ((<SubstitutionType>rootTrueType).substitute).flags & TypeFlags.AnyOrUnknown
|
||||
? (<SubstitutionType>rootTrueType).typeVariable
|
||||
: getIntersectionType([(<SubstitutionType>rootTrueType).substitute, (<SubstitutionType>rootTrueType).typeVariable]);
|
||||
type.resolvedDefaultConstraint = getUnionType([instantiateType(rootTrueConstraint, type.combinedMapper || type.mapper), getFalseTypeFromConditionalType(type)]);
|
||||
}
|
||||
return type.resolvedDefaultConstraint;
|
||||
@@ -19163,12 +19167,12 @@ namespace ts {
|
||||
* @param relation a relationship to check parameter and argument type
|
||||
* @param excludeArgument
|
||||
*/
|
||||
function checkApplicableSignatureForJsxOpeningLikeElement(node: JsxOpeningLikeElement, signature: Signature, relation: Map<RelationComparisonResult>, reportErrors: boolean) {
|
||||
function checkApplicableSignatureForJsxOpeningLikeElement(node: JsxOpeningLikeElement, signature: Signature, relation: Map<RelationComparisonResult>, excludeArgument: boolean[] | undefined, reportErrors: boolean) {
|
||||
// Stateless function components can have maximum of three arguments: "props", "context", and "updater".
|
||||
// However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props,
|
||||
// can be specified by users through attributes property.
|
||||
const paramType = getEffectiveFirstArgumentForJsxSignature(signature, node);
|
||||
const attributesType = checkExpressionWithContextualType(node.attributes, paramType, /*contextualMapper*/ undefined);
|
||||
const attributesType = checkExpressionWithContextualType(node.attributes, paramType, excludeArgument && excludeArgument[0] ? identityMapper : undefined);
|
||||
return checkTypeRelatedToAndOptionallyElaborate(attributesType, paramType, relation, reportErrors ? node.tagName : undefined, node.attributes);
|
||||
}
|
||||
|
||||
@@ -19180,7 +19184,7 @@ namespace ts {
|
||||
excludeArgument: boolean[] | undefined,
|
||||
reportErrors: boolean) {
|
||||
if (isJsxOpeningLikeElement(node)) {
|
||||
return checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation, reportErrors);
|
||||
return checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation, excludeArgument, reportErrors);
|
||||
}
|
||||
const thisType = getThisTypeOfSignature(signature);
|
||||
if (thisType && thisType !== voidType && node.kind !== SyntaxKind.NewExpression) {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
tests/cases/conformance/jsx/file.tsx(13,71): error TS2322: Type 'string' is not assignable to type '{ x: string; }'.
|
||||
tests/cases/conformance/jsx/file.tsx(13,54): error TS2322: Type '(a: { x: string; }) => string' is not assignable to type '((a: { x: string; }) => string) & ((cur: { x: string; }) => { x: string; })'.
|
||||
Type '(a: { x: string; }) => string' is not assignable to type '(cur: { x: string; }) => { x: string; }'.
|
||||
Type 'string' is not assignable to type '{ x: string; }'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsx/file.tsx (1 errors) ====
|
||||
@@ -15,6 +17,8 @@ tests/cases/conformance/jsx/file.tsx(13,71): error TS2322: Type 'string' is not
|
||||
let b = <GenericComponent initialValues={12} nextValues={a => a} />; // No error - Values should be reinstantiated with `number` (since `object` is a default, not a constraint)
|
||||
let c = <GenericComponent initialValues={{ x: "y" }} nextValues={a => ({ x: a.x })} />; // No Error
|
||||
let d = <GenericComponent initialValues={{ x: "y" }} nextValues={a => a.x} />; // Error - `string` is not assignable to `{x: string}`
|
||||
~~~
|
||||
!!! error TS2322: Type 'string' is not assignable to type '{ x: string; }'.
|
||||
!!! related TS6502 tests/cases/conformance/jsx/file.tsx:4:15: The expected type comes from the return type of this signature.
|
||||
~~~~~~~~~~
|
||||
!!! error TS2322: Type '(a: { x: string; }) => string' is not assignable to type '((a: { x: string; }) => string) & ((cur: { x: string; }) => { x: string; })'.
|
||||
!!! error TS2322: Type '(a: { x: string; }) => string' is not assignable to type '(cur: { x: string; }) => { x: string; }'.
|
||||
!!! error TS2322: Type 'string' is not assignable to type '{ x: string; }'.
|
||||
!!! related TS6500 tests/cases/conformance/jsx/file.tsx:13:54: The expected type comes from property 'nextValues' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<GenericComponent<{ initialValues: { x: string; }; nextValues: (a: { x: string; }) => string; }, { x: string; }>> & { initialValues: { x: string; }; nextValues: (a: { x: string; }) => string; } & BaseProps<{ x: string; }> & { children?: ReactNode; }'
|
||||
@@ -0,0 +1,95 @@
|
||||
//// [checkJsxSubtleSkipContextSensitiveBug.tsx]
|
||||
/// <reference path="/.lib/react16.d.ts" />
|
||||
import * as React from "react";
|
||||
|
||||
interface ErrorResult { error: true }
|
||||
|
||||
interface AsyncLoaderProps<TResult> {
|
||||
readonly prop1: () => Promise<TResult>;
|
||||
|
||||
readonly prop2: (result: Exclude<TResult, ErrorResult>) => any;
|
||||
}
|
||||
|
||||
class AsyncLoader<TResult> extends React.Component<AsyncLoaderProps<TResult>> {
|
||||
render() { return null; }
|
||||
}
|
||||
|
||||
async function load(): Promise<{ success: true } | ErrorResult> {
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
const loader = <AsyncLoader
|
||||
prop1={load}
|
||||
prop2={result => result}
|
||||
/>;
|
||||
|
||||
|
||||
//// [checkJsxSubtleSkipContextSensitiveBug.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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
exports.__esModule = true;
|
||||
/// <reference path="react16.d.ts" />
|
||||
var React = require("react");
|
||||
var AsyncLoader = /** @class */ (function (_super) {
|
||||
__extends(AsyncLoader, _super);
|
||||
function AsyncLoader() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
AsyncLoader.prototype.render = function () { return null; };
|
||||
return AsyncLoader;
|
||||
}(React.Component));
|
||||
function load() {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
return [2 /*return*/, { success: true }];
|
||||
});
|
||||
});
|
||||
}
|
||||
var loader = React.createElement(AsyncLoader, { prop1: load, prop2: function (result) { return result; } });
|
||||
@@ -0,0 +1,64 @@
|
||||
=== tests/cases/conformance/jsx/checkJsxSubtleSkipContextSensitiveBug.tsx ===
|
||||
/// <reference path="react16.d.ts" />
|
||||
import * as React from "react";
|
||||
>React : Symbol(React, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 1, 6))
|
||||
|
||||
interface ErrorResult { error: true }
|
||||
>ErrorResult : Symbol(ErrorResult, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 1, 31))
|
||||
>error : Symbol(ErrorResult.error, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 3, 23))
|
||||
|
||||
interface AsyncLoaderProps<TResult> {
|
||||
>AsyncLoaderProps : Symbol(AsyncLoaderProps, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 3, 37))
|
||||
>TResult : Symbol(TResult, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 5, 27))
|
||||
|
||||
readonly prop1: () => Promise<TResult>;
|
||||
>prop1 : Symbol(AsyncLoaderProps.prop1, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 5, 37))
|
||||
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
>TResult : Symbol(TResult, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 5, 27))
|
||||
|
||||
readonly prop2: (result: Exclude<TResult, ErrorResult>) => any;
|
||||
>prop2 : Symbol(AsyncLoaderProps.prop2, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 6, 43))
|
||||
>result : Symbol(result, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 8, 21))
|
||||
>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --))
|
||||
>TResult : Symbol(TResult, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 5, 27))
|
||||
>ErrorResult : Symbol(ErrorResult, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 1, 31))
|
||||
}
|
||||
|
||||
class AsyncLoader<TResult> extends React.Component<AsyncLoaderProps<TResult>> {
|
||||
>AsyncLoader : Symbol(AsyncLoader, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 9, 1))
|
||||
>TResult : Symbol(TResult, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 11, 18))
|
||||
>React.Component : Symbol(React.Component, Decl(react16.d.ts, 345, 54), Decl(react16.d.ts, 349, 94))
|
||||
>React : Symbol(React, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 1, 6))
|
||||
>Component : Symbol(React.Component, Decl(react16.d.ts, 345, 54), Decl(react16.d.ts, 349, 94))
|
||||
>AsyncLoaderProps : Symbol(AsyncLoaderProps, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 3, 37))
|
||||
>TResult : Symbol(TResult, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 11, 18))
|
||||
|
||||
render() { return null; }
|
||||
>render : Symbol(AsyncLoader.render, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 11, 79))
|
||||
}
|
||||
|
||||
async function load(): Promise<{ success: true } | ErrorResult> {
|
||||
>load : Symbol(load, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 13, 1))
|
||||
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
>success : Symbol(success, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 15, 32))
|
||||
>ErrorResult : Symbol(ErrorResult, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 1, 31))
|
||||
|
||||
return { success: true };
|
||||
>success : Symbol(success, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 16, 12))
|
||||
}
|
||||
|
||||
const loader = <AsyncLoader
|
||||
>loader : Symbol(loader, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 19, 5))
|
||||
>AsyncLoader : Symbol(AsyncLoader, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 9, 1))
|
||||
|
||||
prop1={load}
|
||||
>prop1 : Symbol(prop1, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 19, 27))
|
||||
>load : Symbol(load, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 13, 1))
|
||||
|
||||
prop2={result => result}
|
||||
>prop2 : Symbol(prop2, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 20, 16))
|
||||
>result : Symbol(result, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 21, 11))
|
||||
>result : Symbol(result, Decl(checkJsxSubtleSkipContextSensitiveBug.tsx, 21, 11))
|
||||
|
||||
/>;
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
=== tests/cases/conformance/jsx/checkJsxSubtleSkipContextSensitiveBug.tsx ===
|
||||
/// <reference path="react16.d.ts" />
|
||||
import * as React from "react";
|
||||
>React : typeof React
|
||||
|
||||
interface ErrorResult { error: true }
|
||||
>error : true
|
||||
>true : true
|
||||
|
||||
interface AsyncLoaderProps<TResult> {
|
||||
readonly prop1: () => Promise<TResult>;
|
||||
>prop1 : () => Promise<TResult>
|
||||
|
||||
readonly prop2: (result: Exclude<TResult, ErrorResult>) => any;
|
||||
>prop2 : (result: Exclude<TResult, ErrorResult>) => any
|
||||
>result : Exclude<TResult, ErrorResult>
|
||||
}
|
||||
|
||||
class AsyncLoader<TResult> extends React.Component<AsyncLoaderProps<TResult>> {
|
||||
>AsyncLoader : AsyncLoader<TResult>
|
||||
>React.Component : React.Component<AsyncLoaderProps<TResult>, {}, any>
|
||||
>React : typeof React
|
||||
>Component : typeof React.Component
|
||||
|
||||
render() { return null; }
|
||||
>render : () => null
|
||||
>null : null
|
||||
}
|
||||
|
||||
async function load(): Promise<{ success: true } | ErrorResult> {
|
||||
>load : () => Promise<ErrorResult | { success: true; }>
|
||||
>success : true
|
||||
>true : true
|
||||
|
||||
return { success: true };
|
||||
>{ success: true } : { success: true; }
|
||||
>success : true
|
||||
>true : true
|
||||
}
|
||||
|
||||
const loader = <AsyncLoader
|
||||
>loader : JSX.Element
|
||||
><AsyncLoader prop1={load} prop2={result => result}/> : JSX.Element
|
||||
>AsyncLoader : typeof AsyncLoader
|
||||
|
||||
prop1={load}
|
||||
>prop1 : () => Promise<ErrorResult | { success: true; }>
|
||||
>load : () => Promise<ErrorResult | { success: true; }>
|
||||
|
||||
prop2={result => result}
|
||||
>prop2 : (result: { success: true; }) => { success: true; }
|
||||
>result => result : (result: { success: true; }) => { success: true; }
|
||||
>result : { success: true; }
|
||||
>result : { success: true; }
|
||||
|
||||
/>;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(27,13): error TS2322: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'.
|
||||
Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'.
|
||||
tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(28,13): error TS2322: Type '{ onClick: (k: "left" | "right") => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'.
|
||||
tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(28,13): error TS2322: Type '{ onClick: (k: any) => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'.
|
||||
Property 'onClick' does not exist on type 'IntrinsicAttributes & LinkProps'.
|
||||
tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(29,13): error TS2322: Type '{ extra: true; goTo: "home"; }' is not assignable to type 'IntrinsicAttributes & LinkProps'.
|
||||
Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'.
|
||||
@@ -45,7 +45,7 @@ tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(36,13): err
|
||||
!!! error TS2322: Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'.
|
||||
const b2 = <MainButton onClick={(k)=>{console.log(k)}} extra />; // k has type "left" | "right"
|
||||
~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ onClick: (k: "left" | "right") => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'.
|
||||
!!! error TS2322: Type '{ onClick: (k: any) => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'.
|
||||
!!! error TS2322: Property 'onClick' does not exist on type 'IntrinsicAttributes & LinkProps'.
|
||||
const b3 = <MainButton {...{goTo:"home"}} extra />; // goTo has type"home" | "contact"
|
||||
~~~~~~~~~~
|
||||
|
||||
@@ -81,14 +81,14 @@ const b2 = <MainButton onClick={(k)=>{console.log(k)}} extra />; // k has type
|
||||
>b2 : JSX.Element
|
||||
><MainButton onClick={(k)=>{console.log(k)}} extra /> : JSX.Element
|
||||
>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; }
|
||||
>onClick : (k: "left" | "right") => void
|
||||
>(k)=>{console.log(k)} : (k: "left" | "right") => void
|
||||
>k : "left" | "right"
|
||||
>onClick : (k: any) => void
|
||||
>(k)=>{console.log(k)} : (k: any) => void
|
||||
>k : any
|
||||
>console.log(k) : void
|
||||
>console.log : (message?: any, ...optionalParams: any[]) => void
|
||||
>console : Console
|
||||
>log : (message?: any, ...optionalParams: any[]) => void
|
||||
>k : "left" | "right"
|
||||
>k : any
|
||||
>extra : true
|
||||
|
||||
const b3 = <MainButton {...{goTo:"home"}} extra />; // goTo has type"home" | "contact"
|
||||
|
||||
@@ -40,7 +40,7 @@ tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx(64,37): error TS2322:
|
||||
!!! error TS2322: Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean) | undefined'.
|
||||
!!! error TS2322: Type '(value: string) => void' is not assignable to type '(value: string) => boolean'.
|
||||
!!! error TS2322: Type 'void' is not assignable to type 'boolean'.
|
||||
!!! related TS6500 tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx:6:3: The expected type comes from property 'when' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<FieldFeedback<BaseProps>> & Pick<Readonly<{ children?: ReactNode; }> & Readonly<BaseProps>, "children" | "error"> & Partial<Pick<Readonly<{ children?: ReactNode; }> & Readonly<BaseProps>, "when">> & Partial<Pick<{ when: () => boolean; }, never>>'
|
||||
!!! related TS6500 tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx:6:3: The expected type comes from property 'when' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<FieldFeedback<Props>> & Pick<Readonly<{ children?: ReactNode; }> & Readonly<Props>, "children" | "error"> & Partial<Pick<Readonly<{ children?: ReactNode; }> & Readonly<Props>, "when">> & Partial<Pick<{ when: () => boolean; }, never>>'
|
||||
|
||||
class FieldFeedbackBeta<P extends Props = BaseProps> extends React.Component<P> {
|
||||
static defaultProps: BaseProps = {
|
||||
@@ -61,7 +61,7 @@ tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx(64,37): error TS2322:
|
||||
!!! error TS2322: Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean) | undefined'.
|
||||
!!! error TS2322: Type '(value: string) => void' is not assignable to type '(value: string) => boolean'.
|
||||
!!! error TS2322: Type 'void' is not assignable to type 'boolean'.
|
||||
!!! related TS6500 tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx:6:3: The expected type comes from property 'when' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<FieldFeedbackBeta<BaseProps>> & Pick<Readonly<{ children?: ReactNode; }> & Readonly<BaseProps>, "children"> & Partial<Pick<Readonly<{ children?: ReactNode; }> & Readonly<BaseProps>, "when" | "error">> & Partial<Pick<BaseProps, never>>'
|
||||
!!! related TS6500 tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx:6:3: The expected type comes from property 'when' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<FieldFeedbackBeta<Props>> & Pick<Readonly<{ children?: ReactNode; }> & Readonly<Props>, "children"> & Partial<Pick<Readonly<{ children?: ReactNode; }> & Readonly<Props>, "when" | "error">> & Partial<Pick<BaseProps, never>>'
|
||||
|
||||
interface MyPropsProps extends Props {
|
||||
when: (value: string) => boolean;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
tests/cases/conformance/jsx/file.tsx(48,13): error TS2322: Type '{ children: string; to: string; onClick: (e: MouseEvent<any>) => void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'.
|
||||
tests/cases/conformance/jsx/file.tsx(48,13): error TS2322: Type '{ children: string; to: string; onClick: (e: any) => void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'.
|
||||
Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'.
|
||||
tests/cases/conformance/jsx/file.tsx(54,51): error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsx/file.tsx(55,68): error TS2322: Type 'true' is not assignable to type 'string'.
|
||||
@@ -55,7 +55,7 @@ tests/cases/conformance/jsx/file.tsx(56,24): error TS2322: Type 'true' is not as
|
||||
// Error
|
||||
const b0 = <MainButton to='/some/path' onClick={(e)=>{}}>GO</MainButton>; // extra property;
|
||||
~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ children: string; to: string; onClick: (e: MouseEvent<any>) => void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'.
|
||||
!!! error TS2322: Type '{ children: string; to: string; onClick: (e: any) => void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'.
|
||||
!!! error TS2322: Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'.
|
||||
const b1 = <MainButton onClick={(e: any)=> {}} {...obj0}>Hello world</MainButton>; // extra property;
|
||||
const b2 = <MainButton {...{to: "10000"}} {...obj2} />; // extra property
|
||||
|
||||
@@ -113,9 +113,9 @@ const b0 = <MainButton to='/some/path' onClick={(e)=>{}}>GO</MainButton>; // ex
|
||||
><MainButton to='/some/path' onClick={(e)=>{}}>GO</MainButton> : JSX.Element
|
||||
>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; }
|
||||
>to : string
|
||||
>onClick : (e: React.MouseEvent<any>) => void
|
||||
>(e)=>{} : (e: React.MouseEvent<any>) => void
|
||||
>e : React.MouseEvent<any>
|
||||
>onClick : (e: any) => void
|
||||
>(e)=>{} : (e: any) => void
|
||||
>e : any
|
||||
>MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; }
|
||||
|
||||
const b1 = <MainButton onClick={(e: any)=> {}} {...obj0}>Hello world</MainButton>; // extra property;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// @strict: true
|
||||
// @jsx: react
|
||||
// @lib: es6
|
||||
// @skipLibCheck: true
|
||||
/// <reference path="/.lib/react16.d.ts" />
|
||||
import * as React from "react";
|
||||
|
||||
interface ErrorResult { error: true }
|
||||
|
||||
interface AsyncLoaderProps<TResult> {
|
||||
readonly prop1: () => Promise<TResult>;
|
||||
|
||||
readonly prop2: (result: Exclude<TResult, ErrorResult>) => any;
|
||||
}
|
||||
|
||||
class AsyncLoader<TResult> extends React.Component<AsyncLoaderProps<TResult>> {
|
||||
render() { return null; }
|
||||
}
|
||||
|
||||
async function load(): Promise<{ success: true } | ErrorResult> {
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
const loader = <AsyncLoader
|
||||
prop1={load}
|
||||
prop2={result => result}
|
||||
/>;
|
||||
Reference in New Issue
Block a user