mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-11 17:41:26 -06:00
Fixing react defaultize+generic default props interaction (#27088)
* Add repro for fixed issue * Fix JSX propagating flags and contextual types * Accept slightly changed baselines * Add modern react.d.ts and regression test
This commit is contained in:
parent
bce34ada8f
commit
4eb59a2d77
@ -17361,12 +17361,14 @@ namespace ts {
|
||||
let hasSpreadAnyType = false;
|
||||
let typeToIntersect: Type | undefined;
|
||||
let explicitlySpecifyChildrenAttribute = false;
|
||||
let propagatingFlags: TypeFlags = 0;
|
||||
const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(openingLikeElement));
|
||||
|
||||
for (const attributeDecl of attributes.properties) {
|
||||
const member = attributeDecl.symbol;
|
||||
if (isJsxAttribute(attributeDecl)) {
|
||||
const exprType = checkJsxAttribute(attributeDecl, checkMode);
|
||||
propagatingFlags |= (exprType.flags & TypeFlags.PropagatingFlags);
|
||||
|
||||
const attributeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | member.flags, member.escapedName);
|
||||
attributeSymbol.declarations = member.declarations;
|
||||
@ -17384,7 +17386,7 @@ namespace ts {
|
||||
else {
|
||||
Debug.assert(attributeDecl.kind === SyntaxKind.JsxSpreadAttribute);
|
||||
if (attributesTable.size > 0) {
|
||||
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, /*typeFlags*/ 0, ObjectFlags.JsxAttributes);
|
||||
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, propagatingFlags, ObjectFlags.JsxAttributes);
|
||||
attributesTable = createSymbolTable();
|
||||
}
|
||||
const exprType = checkExpressionCached(attributeDecl.expression, checkMode);
|
||||
@ -17392,7 +17394,7 @@ namespace ts {
|
||||
hasSpreadAnyType = true;
|
||||
}
|
||||
if (isValidSpreadType(exprType)) {
|
||||
spread = getSpreadType(spread, exprType, openingLikeElement.symbol, /*typeFlags*/ 0, ObjectFlags.JsxAttributes);
|
||||
spread = getSpreadType(spread, exprType, openingLikeElement.symbol, propagatingFlags, ObjectFlags.JsxAttributes);
|
||||
}
|
||||
else {
|
||||
typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType;
|
||||
@ -17402,7 +17404,7 @@ namespace ts {
|
||||
|
||||
if (!hasSpreadAnyType) {
|
||||
if (attributesTable.size > 0) {
|
||||
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, /*typeFlags*/ 0, ObjectFlags.JsxAttributes);
|
||||
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, propagatingFlags, ObjectFlags.JsxAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
@ -17428,7 +17430,7 @@ namespace ts {
|
||||
const childPropMap = createSymbolTable();
|
||||
childPropMap.set(jsxChildrenPropertyName, childrenPropSymbol);
|
||||
spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined),
|
||||
attributes.symbol, /*typeFlags*/ 0, ObjectFlags.JsxAttributes);
|
||||
attributes.symbol, propagatingFlags, ObjectFlags.JsxAttributes);
|
||||
|
||||
}
|
||||
}
|
||||
@ -17448,7 +17450,7 @@ namespace ts {
|
||||
*/
|
||||
function createJsxAttributesType() {
|
||||
const result = createAnonymousType(attributes.symbol, attributesTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
|
||||
result.flags |= TypeFlags.ContainsObjectLiteral;
|
||||
result.flags |= (propagatingFlags |= TypeFlags.ContainsObjectLiteral);
|
||||
result.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.JsxAttributes;
|
||||
return result;
|
||||
}
|
||||
@ -21957,7 +21959,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getContextNode(node: Expression): Node {
|
||||
if (node.kind === SyntaxKind.JsxAttributes) {
|
||||
if (node.kind === SyntaxKind.JsxAttributes && !isJsxSelfClosingElement(node.parent)) {
|
||||
return node.parent.parent; // Needs to be the root JsxElement, so it encompasses the attributes _and_ the children (which are essentially part of the attributes)
|
||||
}
|
||||
return node;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
tests/cases/conformance/jsx/file.tsx(13,54): error TS2322: 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(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) ====
|
||||
@ -17,6 +18,7 @@ tests/cases/conformance/jsx/file.tsx(13,54): error TS2322: Type '(a: { x: string
|
||||
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 '(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: {}; }, { x: string; }>> & { initialValues: { x: string; }; nextValues: {}; } & BaseProps<{ x: string; }> & { children?: ReactNode; }'
|
||||
!!! 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,25 @@
|
||||
//// [conditionalTypeContextualTypeSimplificationsSuceeds.ts]
|
||||
// repro from https://github.com/Microsoft/TypeScript/issues/26395
|
||||
interface Props {
|
||||
when: (value: string) => boolean;
|
||||
}
|
||||
|
||||
function bad<P extends Props>(
|
||||
attrs: string extends keyof P ? { [K in keyof P]: P[K] } : { [K in keyof P]: P[K] }) { }
|
||||
function good1<P extends Props>(
|
||||
attrs: string extends keyof P ? P : { [K in keyof P]: P[K] }) { }
|
||||
function good2<P extends Props>(
|
||||
attrs: { [K in keyof P]: P[K] }) { }
|
||||
|
||||
bad({ when: value => false });
|
||||
good1({ when: value => false });
|
||||
good2({ when: value => false });
|
||||
|
||||
//// [conditionalTypeContextualTypeSimplificationsSuceeds.js]
|
||||
"use strict";
|
||||
function bad(attrs) { }
|
||||
function good1(attrs) { }
|
||||
function good2(attrs) { }
|
||||
bad({ when: function (value) { return false; } });
|
||||
good1({ when: function (value) { return false; } });
|
||||
good2({ when: function (value) { return false; } });
|
||||
@ -0,0 +1,68 @@
|
||||
=== tests/cases/compiler/conditionalTypeContextualTypeSimplificationsSuceeds.ts ===
|
||||
// repro from https://github.com/Microsoft/TypeScript/issues/26395
|
||||
interface Props {
|
||||
>Props : Symbol(Props, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 0, 0))
|
||||
|
||||
when: (value: string) => boolean;
|
||||
>when : Symbol(Props.when, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 1, 17))
|
||||
>value : Symbol(value, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 2, 11))
|
||||
}
|
||||
|
||||
function bad<P extends Props>(
|
||||
>bad : Symbol(bad, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 3, 1))
|
||||
>P : Symbol(P, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 5, 13))
|
||||
>Props : Symbol(Props, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 0, 0))
|
||||
|
||||
attrs: string extends keyof P ? { [K in keyof P]: P[K] } : { [K in keyof P]: P[K] }) { }
|
||||
>attrs : Symbol(attrs, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 5, 30))
|
||||
>P : Symbol(P, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 5, 13))
|
||||
>K : Symbol(K, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 6, 39))
|
||||
>P : Symbol(P, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 5, 13))
|
||||
>P : Symbol(P, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 5, 13))
|
||||
>K : Symbol(K, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 6, 39))
|
||||
>K : Symbol(K, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 6, 66))
|
||||
>P : Symbol(P, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 5, 13))
|
||||
>P : Symbol(P, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 5, 13))
|
||||
>K : Symbol(K, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 6, 66))
|
||||
|
||||
function good1<P extends Props>(
|
||||
>good1 : Symbol(good1, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 6, 92))
|
||||
>P : Symbol(P, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 7, 15))
|
||||
>Props : Symbol(Props, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 0, 0))
|
||||
|
||||
attrs: string extends keyof P ? P : { [K in keyof P]: P[K] }) { }
|
||||
>attrs : Symbol(attrs, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 7, 32))
|
||||
>P : Symbol(P, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 7, 15))
|
||||
>P : Symbol(P, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 7, 15))
|
||||
>K : Symbol(K, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 8, 43))
|
||||
>P : Symbol(P, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 7, 15))
|
||||
>P : Symbol(P, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 7, 15))
|
||||
>K : Symbol(K, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 8, 43))
|
||||
|
||||
function good2<P extends Props>(
|
||||
>good2 : Symbol(good2, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 8, 69))
|
||||
>P : Symbol(P, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 9, 15))
|
||||
>Props : Symbol(Props, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 0, 0))
|
||||
|
||||
attrs: { [K in keyof P]: P[K] }) { }
|
||||
>attrs : Symbol(attrs, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 9, 32))
|
||||
>K : Symbol(K, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 10, 14))
|
||||
>P : Symbol(P, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 9, 15))
|
||||
>P : Symbol(P, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 9, 15))
|
||||
>K : Symbol(K, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 10, 14))
|
||||
|
||||
bad({ when: value => false });
|
||||
>bad : Symbol(bad, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 3, 1))
|
||||
>when : Symbol(when, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 12, 5))
|
||||
>value : Symbol(value, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 12, 11))
|
||||
|
||||
good1({ when: value => false });
|
||||
>good1 : Symbol(good1, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 6, 92))
|
||||
>when : Symbol(when, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 13, 7))
|
||||
>value : Symbol(value, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 13, 13))
|
||||
|
||||
good2({ when: value => false });
|
||||
>good2 : Symbol(good2, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 8, 69))
|
||||
>when : Symbol(when, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 14, 7))
|
||||
>value : Symbol(value, Decl(conditionalTypeContextualTypeSimplificationsSuceeds.ts, 14, 13))
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
=== tests/cases/compiler/conditionalTypeContextualTypeSimplificationsSuceeds.ts ===
|
||||
// repro from https://github.com/Microsoft/TypeScript/issues/26395
|
||||
interface Props {
|
||||
when: (value: string) => boolean;
|
||||
>when : (value: string) => boolean
|
||||
>value : string
|
||||
}
|
||||
|
||||
function bad<P extends Props>(
|
||||
>bad : <P extends Props>(attrs: string extends keyof P ? { [K in keyof P]: P[K]; } : { [K in keyof P]: P[K]; }) => void
|
||||
|
||||
attrs: string extends keyof P ? { [K in keyof P]: P[K] } : { [K in keyof P]: P[K] }) { }
|
||||
>attrs : string extends keyof P ? { [K in keyof P]: P[K]; } : { [K in keyof P]: P[K]; }
|
||||
|
||||
function good1<P extends Props>(
|
||||
>good1 : <P extends Props>(attrs: string extends keyof P ? P : { [K in keyof P]: P[K]; }) => void
|
||||
|
||||
attrs: string extends keyof P ? P : { [K in keyof P]: P[K] }) { }
|
||||
>attrs : string extends keyof P ? P : { [K in keyof P]: P[K]; }
|
||||
|
||||
function good2<P extends Props>(
|
||||
>good2 : <P extends Props>(attrs: { [K in keyof P]: P[K]; }) => void
|
||||
|
||||
attrs: { [K in keyof P]: P[K] }) { }
|
||||
>attrs : { [K in keyof P]: P[K]; }
|
||||
|
||||
bad({ when: value => false });
|
||||
>bad({ when: value => false }) : void
|
||||
>bad : <P extends Props>(attrs: string extends keyof P ? { [K in keyof P]: P[K]; } : { [K in keyof P]: P[K]; }) => void
|
||||
>{ when: value => false } : { when: (value: string) => false; }
|
||||
>when : (value: string) => false
|
||||
>value => false : (value: string) => false
|
||||
>value : string
|
||||
>false : false
|
||||
|
||||
good1({ when: value => false });
|
||||
>good1({ when: value => false }) : void
|
||||
>good1 : <P extends Props>(attrs: string extends keyof P ? P : { [K in keyof P]: P[K]; }) => void
|
||||
>{ when: value => false } : { when: (value: string) => false; }
|
||||
>when : (value: string) => false
|
||||
>value => false : (value: string) => false
|
||||
>value : string
|
||||
>false : false
|
||||
|
||||
good2({ when: value => false });
|
||||
>good2({ when: value => false }) : void
|
||||
>good2 : <P extends Props>(attrs: { [K in keyof P]: P[K]; }) => void
|
||||
>{ when: value => false } : { when: (value: string) => false; }
|
||||
>when : (value: string) => false
|
||||
>value => false : (value: string) => false
|
||||
>value : string
|
||||
>false : false
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx(20,31): error TS2322: Type '(p: IntrinsicAttributes & LitProps<"x">) => "y"' is not assignable to type '(x: IntrinsicAttributes & LitProps<"x">) => "x"'.
|
||||
tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx(20,31): error TS2322: Type '(p: LitProps<"x">) => "y"' is not assignable to type '(x: IntrinsicAttributes & LitProps<"x">) => "x"'.
|
||||
Type '"y"' is not assignable to type '"x"'.
|
||||
tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx(21,19): error TS2322: Type '{ children: (p: IntrinsicAttributes & LitProps<"x">) => "y"; prop: "x"; }' is not assignable to type 'IntrinsicAttributes & LitProps<"x" | "y">'.
|
||||
Type '{ children: (p: IntrinsicAttributes & LitProps<"x">) => "y"; prop: "x"; }' is not assignable to type 'LitProps<"x" | "y">'.
|
||||
@ -39,7 +39,7 @@ tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx(22,21): error TS2322:
|
||||
// Should error
|
||||
const arg = <ElemLit prop="x" children={p => "y"} />
|
||||
~~~~~~~~
|
||||
!!! error TS2322: Type '(p: IntrinsicAttributes & LitProps<"x">) => "y"' is not assignable to type '(x: IntrinsicAttributes & LitProps<"x">) => "x"'.
|
||||
!!! error TS2322: Type '(p: LitProps<"x">) => "y"' is not assignable to type '(x: IntrinsicAttributes & LitProps<"x">) => "x"'.
|
||||
!!! error TS2322: Type '"y"' is not assignable to type '"x"'.
|
||||
!!! related TS6500 tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx:13:34: The expected type comes from property 'children' which is declared here on type 'IntrinsicAttributes & LitProps<"x">'
|
||||
const argchild = <ElemLit prop="x">{p => "y"}</ElemLit>
|
||||
|
||||
@ -117,9 +117,9 @@ const arg = <ElemLit prop="x" children={p => "y"} />
|
||||
><ElemLit prop="x" children={p => "y"} /> : JSX.Element
|
||||
>ElemLit : <T extends string>(p: LitProps<T>) => JSX.Element
|
||||
>prop : "x"
|
||||
>children : (p: JSX.IntrinsicAttributes & LitProps<"x">) => "y"
|
||||
>p => "y" : (p: JSX.IntrinsicAttributes & LitProps<"x">) => "y"
|
||||
>p : JSX.IntrinsicAttributes & LitProps<"x">
|
||||
>children : (p: LitProps<"x">) => "y"
|
||||
>p => "y" : (p: LitProps<"x">) => "y"
|
||||
>p : LitProps<"x">
|
||||
>"y" : "y"
|
||||
|
||||
const argchild = <ElemLit prop="x">{p => "y"}</ElemLit>
|
||||
|
||||
@ -0,0 +1,67 @@
|
||||
tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx(26,36): error TS2322: Type '(value: string) => void' is not assignable to type '(value: string) => boolean'.
|
||||
Type 'void' is not assignable to type 'boolean'.
|
||||
tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx(48,37): error TS2322: Type '(value: string) => void' is not assignable to type '(value: string) => boolean'.
|
||||
Type 'void' is not assignable to type 'boolean'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx (2 errors) ====
|
||||
/// <reference path="/.lib/react16.d.ts" />
|
||||
|
||||
import React from 'react';
|
||||
|
||||
interface BaseProps {
|
||||
when?: (value: string) => boolean;
|
||||
}
|
||||
|
||||
interface Props extends BaseProps {
|
||||
}
|
||||
|
||||
class FieldFeedback<P extends Props = BaseProps> extends React.Component<P> {
|
||||
static defaultProps = {
|
||||
when: () => true
|
||||
};
|
||||
|
||||
render() {
|
||||
return <div>Hello</div>;
|
||||
}
|
||||
}
|
||||
|
||||
// OK
|
||||
const Test1 = () => <FieldFeedback when={value => !!value} />;
|
||||
|
||||
// Error: Void not assignable to boolean
|
||||
const Test2 = () => <FieldFeedback when={value => console.log(value)} />;
|
||||
~~~~
|
||||
!!! 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<Props>> & Pick<Readonly<{ children?: ReactNode; }> & Readonly<Props>, "children"> & Partial<Pick<Readonly<{ children?: ReactNode; }> & Readonly<Props>, "when">> & Partial<Pick<{ when: () => boolean; }, never>>'
|
||||
|
||||
|
||||
interface MyPropsProps extends Props {
|
||||
when: (value: string) => boolean;
|
||||
}
|
||||
|
||||
class FieldFeedback2<P extends MyPropsProps = MyPropsProps> extends FieldFeedback<P> {
|
||||
static defaultProps = {
|
||||
when: () => true
|
||||
};
|
||||
|
||||
render() {
|
||||
this.props.when("now"); // OK, always defined
|
||||
return <div>Hello</div>;
|
||||
}
|
||||
}
|
||||
|
||||
// OK
|
||||
const Test3 = () => <FieldFeedback2 when={value => !!value} />;
|
||||
|
||||
// Error: Void not assignable to boolean
|
||||
const Test4 = () => <FieldFeedback2 when={value => console.log(value)} />;
|
||||
~~~~
|
||||
!!! 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:30:3: The expected type comes from property 'when' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<FieldFeedback2<MyPropsProps>> & Pick<Readonly<{ children?: ReactNode; }> & Readonly<MyPropsProps>, "children"> & Partial<Pick<Readonly<{ children?: ReactNode; }> & Readonly<MyPropsProps>, "when">> & Partial<Pick<{ when: () => boolean; }, never>>'
|
||||
|
||||
// OK
|
||||
const Test5 = () => <FieldFeedback2 />;
|
||||
|
||||
112
tests/baselines/reference/reactDefaultPropsInferenceSuccess.js
Normal file
112
tests/baselines/reference/reactDefaultPropsInferenceSuccess.js
Normal file
@ -0,0 +1,112 @@
|
||||
//// [reactDefaultPropsInferenceSuccess.tsx]
|
||||
/// <reference path="/.lib/react16.d.ts" />
|
||||
|
||||
import React from 'react';
|
||||
|
||||
interface BaseProps {
|
||||
when?: (value: string) => boolean;
|
||||
}
|
||||
|
||||
interface Props extends BaseProps {
|
||||
}
|
||||
|
||||
class FieldFeedback<P extends Props = BaseProps> extends React.Component<P> {
|
||||
static defaultProps = {
|
||||
when: () => true
|
||||
};
|
||||
|
||||
render() {
|
||||
return <div>Hello</div>;
|
||||
}
|
||||
}
|
||||
|
||||
// OK
|
||||
const Test1 = () => <FieldFeedback when={value => !!value} />;
|
||||
|
||||
// Error: Void not assignable to boolean
|
||||
const Test2 = () => <FieldFeedback when={value => console.log(value)} />;
|
||||
|
||||
|
||||
interface MyPropsProps extends Props {
|
||||
when: (value: string) => boolean;
|
||||
}
|
||||
|
||||
class FieldFeedback2<P extends MyPropsProps = MyPropsProps> extends FieldFeedback<P> {
|
||||
static defaultProps = {
|
||||
when: () => true
|
||||
};
|
||||
|
||||
render() {
|
||||
this.props.when("now"); // OK, always defined
|
||||
return <div>Hello</div>;
|
||||
}
|
||||
}
|
||||
|
||||
// OK
|
||||
const Test3 = () => <FieldFeedback2 when={value => !!value} />;
|
||||
|
||||
// Error: Void not assignable to boolean
|
||||
const Test4 = () => <FieldFeedback2 when={value => console.log(value)} />;
|
||||
|
||||
// OK
|
||||
const Test5 = () => <FieldFeedback2 />;
|
||||
|
||||
|
||||
//// [reactDefaultPropsInferenceSuccess.js]
|
||||
"use strict";
|
||||
/// <reference path="react16.d.ts" />
|
||||
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 __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
exports.__esModule = true;
|
||||
var react_1 = __importDefault(require("react"));
|
||||
var FieldFeedback = /** @class */ (function (_super) {
|
||||
__extends(FieldFeedback, _super);
|
||||
function FieldFeedback() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
FieldFeedback.prototype.render = function () {
|
||||
return react_1["default"].createElement("div", null, "Hello");
|
||||
};
|
||||
FieldFeedback.defaultProps = {
|
||||
when: function () { return true; }
|
||||
};
|
||||
return FieldFeedback;
|
||||
}(react_1["default"].Component));
|
||||
// OK
|
||||
var Test1 = function () { return react_1["default"].createElement(FieldFeedback, { when: function (value) { return !!value; } }); };
|
||||
// Error: Void not assignable to boolean
|
||||
var Test2 = function () { return react_1["default"].createElement(FieldFeedback, { when: function (value) { return console.log(value); } }); };
|
||||
var FieldFeedback2 = /** @class */ (function (_super) {
|
||||
__extends(FieldFeedback2, _super);
|
||||
function FieldFeedback2() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
FieldFeedback2.prototype.render = function () {
|
||||
this.props.when("now"); // OK, always defined
|
||||
return react_1["default"].createElement("div", null, "Hello");
|
||||
};
|
||||
FieldFeedback2.defaultProps = {
|
||||
when: function () { return true; }
|
||||
};
|
||||
return FieldFeedback2;
|
||||
}(FieldFeedback));
|
||||
// OK
|
||||
var Test3 = function () { return react_1["default"].createElement(FieldFeedback2, { when: function (value) { return !!value; } }); };
|
||||
// Error: Void not assignable to boolean
|
||||
var Test4 = function () { return react_1["default"].createElement(FieldFeedback2, { when: function (value) { return console.log(value); } }); };
|
||||
// OK
|
||||
var Test5 = function () { return react_1["default"].createElement(FieldFeedback2, null); };
|
||||
@ -0,0 +1,131 @@
|
||||
=== tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx ===
|
||||
/// <reference path="react16.d.ts" />
|
||||
|
||||
import React from 'react';
|
||||
>React : Symbol(React, Decl(reactDefaultPropsInferenceSuccess.tsx, 2, 6))
|
||||
|
||||
interface BaseProps {
|
||||
>BaseProps : Symbol(BaseProps, Decl(reactDefaultPropsInferenceSuccess.tsx, 2, 26))
|
||||
|
||||
when?: (value: string) => boolean;
|
||||
>when : Symbol(BaseProps.when, Decl(reactDefaultPropsInferenceSuccess.tsx, 4, 21))
|
||||
>value : Symbol(value, Decl(reactDefaultPropsInferenceSuccess.tsx, 5, 10))
|
||||
}
|
||||
|
||||
interface Props extends BaseProps {
|
||||
>Props : Symbol(Props, Decl(reactDefaultPropsInferenceSuccess.tsx, 6, 1))
|
||||
>BaseProps : Symbol(BaseProps, Decl(reactDefaultPropsInferenceSuccess.tsx, 2, 26))
|
||||
}
|
||||
|
||||
class FieldFeedback<P extends Props = BaseProps> extends React.Component<P> {
|
||||
>FieldFeedback : Symbol(FieldFeedback, Decl(reactDefaultPropsInferenceSuccess.tsx, 9, 1))
|
||||
>P : Symbol(P, Decl(reactDefaultPropsInferenceSuccess.tsx, 11, 20))
|
||||
>Props : Symbol(Props, Decl(reactDefaultPropsInferenceSuccess.tsx, 6, 1))
|
||||
>BaseProps : Symbol(BaseProps, Decl(reactDefaultPropsInferenceSuccess.tsx, 2, 26))
|
||||
>React.Component : Symbol(React.Component, Decl(react16.d.ts, 345, 54), Decl(react16.d.ts, 349, 94))
|
||||
>React : Symbol(React, Decl(reactDefaultPropsInferenceSuccess.tsx, 2, 6))
|
||||
>Component : Symbol(React.Component, Decl(react16.d.ts, 345, 54), Decl(react16.d.ts, 349, 94))
|
||||
>P : Symbol(P, Decl(reactDefaultPropsInferenceSuccess.tsx, 11, 20))
|
||||
|
||||
static defaultProps = {
|
||||
>defaultProps : Symbol(FieldFeedback.defaultProps, Decl(reactDefaultPropsInferenceSuccess.tsx, 11, 77))
|
||||
|
||||
when: () => true
|
||||
>when : Symbol(when, Decl(reactDefaultPropsInferenceSuccess.tsx, 12, 25))
|
||||
|
||||
};
|
||||
|
||||
render() {
|
||||
>render : Symbol(FieldFeedback.render, Decl(reactDefaultPropsInferenceSuccess.tsx, 14, 4))
|
||||
|
||||
return <div>Hello</div>;
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
}
|
||||
}
|
||||
|
||||
// OK
|
||||
const Test1 = () => <FieldFeedback when={value => !!value} />;
|
||||
>Test1 : Symbol(Test1, Decl(reactDefaultPropsInferenceSuccess.tsx, 22, 5))
|
||||
>FieldFeedback : Symbol(FieldFeedback, Decl(reactDefaultPropsInferenceSuccess.tsx, 9, 1))
|
||||
>when : Symbol(when, Decl(reactDefaultPropsInferenceSuccess.tsx, 22, 34))
|
||||
>value : Symbol(value, Decl(reactDefaultPropsInferenceSuccess.tsx, 22, 41))
|
||||
>value : Symbol(value, Decl(reactDefaultPropsInferenceSuccess.tsx, 22, 41))
|
||||
|
||||
// Error: Void not assignable to boolean
|
||||
const Test2 = () => <FieldFeedback when={value => console.log(value)} />;
|
||||
>Test2 : Symbol(Test2, Decl(reactDefaultPropsInferenceSuccess.tsx, 25, 5))
|
||||
>FieldFeedback : Symbol(FieldFeedback, Decl(reactDefaultPropsInferenceSuccess.tsx, 9, 1))
|
||||
>when : Symbol(when, Decl(reactDefaultPropsInferenceSuccess.tsx, 25, 34))
|
||||
>value : Symbol(value, Decl(reactDefaultPropsInferenceSuccess.tsx, 25, 41))
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>value : Symbol(value, Decl(reactDefaultPropsInferenceSuccess.tsx, 25, 41))
|
||||
|
||||
|
||||
interface MyPropsProps extends Props {
|
||||
>MyPropsProps : Symbol(MyPropsProps, Decl(reactDefaultPropsInferenceSuccess.tsx, 25, 73))
|
||||
>Props : Symbol(Props, Decl(reactDefaultPropsInferenceSuccess.tsx, 6, 1))
|
||||
|
||||
when: (value: string) => boolean;
|
||||
>when : Symbol(MyPropsProps.when, Decl(reactDefaultPropsInferenceSuccess.tsx, 28, 38))
|
||||
>value : Symbol(value, Decl(reactDefaultPropsInferenceSuccess.tsx, 29, 9))
|
||||
}
|
||||
|
||||
class FieldFeedback2<P extends MyPropsProps = MyPropsProps> extends FieldFeedback<P> {
|
||||
>FieldFeedback2 : Symbol(FieldFeedback2, Decl(reactDefaultPropsInferenceSuccess.tsx, 30, 1))
|
||||
>P : Symbol(P, Decl(reactDefaultPropsInferenceSuccess.tsx, 32, 21))
|
||||
>MyPropsProps : Symbol(MyPropsProps, Decl(reactDefaultPropsInferenceSuccess.tsx, 25, 73))
|
||||
>MyPropsProps : Symbol(MyPropsProps, Decl(reactDefaultPropsInferenceSuccess.tsx, 25, 73))
|
||||
>FieldFeedback : Symbol(FieldFeedback, Decl(reactDefaultPropsInferenceSuccess.tsx, 9, 1))
|
||||
>P : Symbol(P, Decl(reactDefaultPropsInferenceSuccess.tsx, 32, 21))
|
||||
|
||||
static defaultProps = {
|
||||
>defaultProps : Symbol(FieldFeedback2.defaultProps, Decl(reactDefaultPropsInferenceSuccess.tsx, 32, 86))
|
||||
|
||||
when: () => true
|
||||
>when : Symbol(when, Decl(reactDefaultPropsInferenceSuccess.tsx, 33, 25))
|
||||
|
||||
};
|
||||
|
||||
render() {
|
||||
>render : Symbol(FieldFeedback2.render, Decl(reactDefaultPropsInferenceSuccess.tsx, 35, 4))
|
||||
|
||||
this.props.when("now"); // OK, always defined
|
||||
>this.props.when : Symbol(when, Decl(reactDefaultPropsInferenceSuccess.tsx, 28, 38))
|
||||
>this.props : Symbol(React.Component.props, Decl(react16.d.ts, 367, 32))
|
||||
>this : Symbol(FieldFeedback2, Decl(reactDefaultPropsInferenceSuccess.tsx, 30, 1))
|
||||
>props : Symbol(React.Component.props, Decl(react16.d.ts, 367, 32))
|
||||
>when : Symbol(when, Decl(reactDefaultPropsInferenceSuccess.tsx, 28, 38))
|
||||
|
||||
return <div>Hello</div>;
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
}
|
||||
}
|
||||
|
||||
// OK
|
||||
const Test3 = () => <FieldFeedback2 when={value => !!value} />;
|
||||
>Test3 : Symbol(Test3, Decl(reactDefaultPropsInferenceSuccess.tsx, 44, 5))
|
||||
>FieldFeedback2 : Symbol(FieldFeedback2, Decl(reactDefaultPropsInferenceSuccess.tsx, 30, 1))
|
||||
>when : Symbol(when, Decl(reactDefaultPropsInferenceSuccess.tsx, 44, 35))
|
||||
>value : Symbol(value, Decl(reactDefaultPropsInferenceSuccess.tsx, 44, 42))
|
||||
>value : Symbol(value, Decl(reactDefaultPropsInferenceSuccess.tsx, 44, 42))
|
||||
|
||||
// Error: Void not assignable to boolean
|
||||
const Test4 = () => <FieldFeedback2 when={value => console.log(value)} />;
|
||||
>Test4 : Symbol(Test4, Decl(reactDefaultPropsInferenceSuccess.tsx, 47, 5))
|
||||
>FieldFeedback2 : Symbol(FieldFeedback2, Decl(reactDefaultPropsInferenceSuccess.tsx, 30, 1))
|
||||
>when : Symbol(when, Decl(reactDefaultPropsInferenceSuccess.tsx, 47, 35))
|
||||
>value : Symbol(value, Decl(reactDefaultPropsInferenceSuccess.tsx, 47, 42))
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>value : Symbol(value, Decl(reactDefaultPropsInferenceSuccess.tsx, 47, 42))
|
||||
|
||||
// OK
|
||||
const Test5 = () => <FieldFeedback2 />;
|
||||
>Test5 : Symbol(Test5, Decl(reactDefaultPropsInferenceSuccess.tsx, 50, 5))
|
||||
>FieldFeedback2 : Symbol(FieldFeedback2, Decl(reactDefaultPropsInferenceSuccess.tsx, 30, 1))
|
||||
|
||||
@ -0,0 +1,146 @@
|
||||
=== tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx ===
|
||||
/// <reference path="react16.d.ts" />
|
||||
|
||||
import React from 'react';
|
||||
>React : typeof React
|
||||
|
||||
interface BaseProps {
|
||||
when?: (value: string) => boolean;
|
||||
>when : ((value: string) => boolean) | undefined
|
||||
>value : string
|
||||
}
|
||||
|
||||
interface Props extends BaseProps {
|
||||
}
|
||||
|
||||
class FieldFeedback<P extends Props = BaseProps> extends React.Component<P> {
|
||||
>FieldFeedback : FieldFeedback<P>
|
||||
>React.Component : React.Component<P, {}, any>
|
||||
>React : typeof React
|
||||
>Component : typeof React.Component
|
||||
|
||||
static defaultProps = {
|
||||
>defaultProps : { when: () => boolean; }
|
||||
>{ when: () => true } : { when: () => boolean; }
|
||||
|
||||
when: () => true
|
||||
>when : () => boolean
|
||||
>() => true : () => boolean
|
||||
>true : true
|
||||
|
||||
};
|
||||
|
||||
render() {
|
||||
>render : () => JSX.Element
|
||||
|
||||
return <div>Hello</div>;
|
||||
><div>Hello</div> : JSX.Element
|
||||
>div : any
|
||||
>div : any
|
||||
}
|
||||
}
|
||||
|
||||
// OK
|
||||
const Test1 = () => <FieldFeedback when={value => !!value} />;
|
||||
>Test1 : () => JSX.Element
|
||||
>() => <FieldFeedback when={value => !!value} /> : () => JSX.Element
|
||||
><FieldFeedback when={value => !!value} /> : JSX.Element
|
||||
>FieldFeedback : typeof FieldFeedback
|
||||
>when : (value: string) => boolean
|
||||
>value => !!value : (value: string) => boolean
|
||||
>value : string
|
||||
>!!value : boolean
|
||||
>!value : boolean
|
||||
>value : string
|
||||
|
||||
// Error: Void not assignable to boolean
|
||||
const Test2 = () => <FieldFeedback when={value => console.log(value)} />;
|
||||
>Test2 : () => JSX.Element
|
||||
>() => <FieldFeedback when={value => console.log(value)} /> : () => JSX.Element
|
||||
><FieldFeedback when={value => console.log(value)} /> : JSX.Element
|
||||
>FieldFeedback : typeof FieldFeedback
|
||||
>when : (value: string) => void
|
||||
>value => console.log(value) : (value: string) => void
|
||||
>value : string
|
||||
>console.log(value) : void
|
||||
>console.log : (message?: any, ...optionalParams: any[]) => void
|
||||
>console : Console
|
||||
>log : (message?: any, ...optionalParams: any[]) => void
|
||||
>value : string
|
||||
|
||||
|
||||
interface MyPropsProps extends Props {
|
||||
when: (value: string) => boolean;
|
||||
>when : (value: string) => boolean
|
||||
>value : string
|
||||
}
|
||||
|
||||
class FieldFeedback2<P extends MyPropsProps = MyPropsProps> extends FieldFeedback<P> {
|
||||
>FieldFeedback2 : FieldFeedback2<P>
|
||||
>FieldFeedback : FieldFeedback<P>
|
||||
|
||||
static defaultProps = {
|
||||
>defaultProps : { when: () => boolean; }
|
||||
>{ when: () => true } : { when: () => boolean; }
|
||||
|
||||
when: () => true
|
||||
>when : () => boolean
|
||||
>() => true : () => boolean
|
||||
>true : true
|
||||
|
||||
};
|
||||
|
||||
render() {
|
||||
>render : () => JSX.Element
|
||||
|
||||
this.props.when("now"); // OK, always defined
|
||||
>this.props.when("now") : boolean
|
||||
>this.props.when : P["when"]
|
||||
>this.props : Readonly<{ children?: React.ReactNode; }> & Readonly<P>
|
||||
>this : this
|
||||
>props : Readonly<{ children?: React.ReactNode; }> & Readonly<P>
|
||||
>when : P["when"]
|
||||
>"now" : "now"
|
||||
|
||||
return <div>Hello</div>;
|
||||
><div>Hello</div> : JSX.Element
|
||||
>div : any
|
||||
>div : any
|
||||
}
|
||||
}
|
||||
|
||||
// OK
|
||||
const Test3 = () => <FieldFeedback2 when={value => !!value} />;
|
||||
>Test3 : () => JSX.Element
|
||||
>() => <FieldFeedback2 when={value => !!value} /> : () => JSX.Element
|
||||
><FieldFeedback2 when={value => !!value} /> : JSX.Element
|
||||
>FieldFeedback2 : typeof FieldFeedback2
|
||||
>when : (value: string) => boolean
|
||||
>value => !!value : (value: string) => boolean
|
||||
>value : string
|
||||
>!!value : boolean
|
||||
>!value : boolean
|
||||
>value : string
|
||||
|
||||
// Error: Void not assignable to boolean
|
||||
const Test4 = () => <FieldFeedback2 when={value => console.log(value)} />;
|
||||
>Test4 : () => JSX.Element
|
||||
>() => <FieldFeedback2 when={value => console.log(value)} /> : () => JSX.Element
|
||||
><FieldFeedback2 when={value => console.log(value)} /> : JSX.Element
|
||||
>FieldFeedback2 : typeof FieldFeedback2
|
||||
>when : (value: string) => void
|
||||
>value => console.log(value) : (value: string) => void
|
||||
>value : string
|
||||
>console.log(value) : void
|
||||
>console.log : (message?: any, ...optionalParams: any[]) => void
|
||||
>console : Console
|
||||
>log : (message?: any, ...optionalParams: any[]) => void
|
||||
>value : string
|
||||
|
||||
// OK
|
||||
const Test5 = () => <FieldFeedback2 />;
|
||||
>Test5 : () => JSX.Element
|
||||
>() => <FieldFeedback2 /> : () => JSX.Element
|
||||
><FieldFeedback2 /> : JSX.Element
|
||||
>FieldFeedback2 : typeof FieldFeedback2
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
// @strict: true
|
||||
// repro from https://github.com/Microsoft/TypeScript/issues/26395
|
||||
interface Props {
|
||||
when: (value: string) => boolean;
|
||||
}
|
||||
|
||||
function bad<P extends Props>(
|
||||
attrs: string extends keyof P ? { [K in keyof P]: P[K] } : { [K in keyof P]: P[K] }) { }
|
||||
function good1<P extends Props>(
|
||||
attrs: string extends keyof P ? P : { [K in keyof P]: P[K] }) { }
|
||||
function good2<P extends Props>(
|
||||
attrs: { [K in keyof P]: P[K] }) { }
|
||||
|
||||
bad({ when: value => false });
|
||||
good1({ when: value => false });
|
||||
good2({ when: value => false });
|
||||
54
tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx
Normal file
54
tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx
Normal file
@ -0,0 +1,54 @@
|
||||
// @jsx: react
|
||||
// @strict: true
|
||||
// @esModuleInterop: true
|
||||
/// <reference path="/.lib/react16.d.ts" />
|
||||
|
||||
import React from 'react';
|
||||
|
||||
interface BaseProps {
|
||||
when?: (value: string) => boolean;
|
||||
}
|
||||
|
||||
interface Props extends BaseProps {
|
||||
}
|
||||
|
||||
class FieldFeedback<P extends Props = BaseProps> extends React.Component<P> {
|
||||
static defaultProps = {
|
||||
when: () => true
|
||||
};
|
||||
|
||||
render() {
|
||||
return <div>Hello</div>;
|
||||
}
|
||||
}
|
||||
|
||||
// OK
|
||||
const Test1 = () => <FieldFeedback when={value => !!value} />;
|
||||
|
||||
// Error: Void not assignable to boolean
|
||||
const Test2 = () => <FieldFeedback when={value => console.log(value)} />;
|
||||
|
||||
|
||||
interface MyPropsProps extends Props {
|
||||
when: (value: string) => boolean;
|
||||
}
|
||||
|
||||
class FieldFeedback2<P extends MyPropsProps = MyPropsProps> extends FieldFeedback<P> {
|
||||
static defaultProps = {
|
||||
when: () => true
|
||||
};
|
||||
|
||||
render() {
|
||||
this.props.when("now"); // OK, always defined
|
||||
return <div>Hello</div>;
|
||||
}
|
||||
}
|
||||
|
||||
// OK
|
||||
const Test3 = () => <FieldFeedback2 when={value => !!value} />;
|
||||
|
||||
// Error: Void not assignable to boolean
|
||||
const Test4 = () => <FieldFeedback2 when={value => console.log(value)} />;
|
||||
|
||||
// OK
|
||||
const Test5 = () => <FieldFeedback2 />;
|
||||
2569
tests/lib/react16.d.ts
vendored
Normal file
2569
tests/lib/react16.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user