Support LibraryManagedAttributes<TComponent, TAttributes> JSX namespace type (#24422)

* WIP

* Allow type alias for managed type

* Add a large test

* Accept updatedbaselines

* Fix typo in test, add one more example
This commit is contained in:
Wesley Wigham
2018-06-29 18:45:29 -07:00
committed by GitHub
parent 313a0b8990
commit 18e3f487a4
6 changed files with 1635 additions and 4 deletions
+31 -4
View File
@@ -15730,8 +15730,9 @@ namespace ts {
return getUnionType(map(signatures, ctor ? t => getJsxPropsTypeFromClassType(t, isJs, context, /*reportErrors*/ false) : t => getJsxPropsTypeFromCallSignature(t, context)), UnionReduction.None);
}
function getJsxPropsTypeFromCallSignature(sig: Signature, context: Node) {
function getJsxPropsTypeFromCallSignature(sig: Signature, context: JsxOpeningLikeElement) {
let propsType = getTypeOfFirstParameterOfSignatureWithFallback(sig, emptyObjectType);
propsType = getJsxManagedAttributesFromLocatedAttributes(context, getJsxNamespaceAt(context), propsType);
const intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context);
if (intrinsicAttribs !== errorType) {
propsType = intersectTypes(intrinsicAttribs, propsType);
@@ -15744,9 +15745,26 @@ namespace ts {
return isTypeAny(instanceType) ? instanceType : getTypeOfPropertyOfType(instanceType, forcedLookupLocation);
}
function getJsxManagedAttributesFromLocatedAttributes(context: JsxOpeningLikeElement, ns: Symbol, attributesType: Type) {
const managedSym = getJsxLibraryManagedAttributes(ns);
if (managedSym) {
const declaredManagedType = getDeclaredTypeOfSymbol(managedSym);
if (length((declaredManagedType as GenericType).typeParameters) >= 2) {
const args = fillMissingTypeArguments([checkExpressionCached(context.tagName), attributesType], (declaredManagedType as GenericType).typeParameters, 2, isInJavaScriptFile(context));
return createTypeReference((declaredManagedType as GenericType), args);
}
else if (length(declaredManagedType.aliasTypeArguments) >= 2) {
const args = fillMissingTypeArguments([checkExpressionCached(context.tagName), attributesType], declaredManagedType.aliasTypeArguments!, 2, isInJavaScriptFile(context));
return getTypeAliasInstantiation(declaredManagedType.aliasSymbol!, args);
}
}
return attributesType;
}
function getJsxPropsTypeFromClassType(sig: Signature, isJs: boolean, context: JsxOpeningLikeElement, reportErrors: boolean) {
const forcedLookupLocation = getJsxElementPropertiesName(getJsxNamespaceAt(context));
const attributesType = forcedLookupLocation === undefined
const ns = getJsxNamespaceAt(context);
const forcedLookupLocation = getJsxElementPropertiesName(ns);
let attributesType = forcedLookupLocation === undefined
// If there is no type ElementAttributesProperty, return the type of the first parameter of the signature, which should be the props type
? getTypeOfFirstParameterOfSignatureWithFallback(sig, emptyObjectType)
: forcedLookupLocation === ""
@@ -15762,7 +15780,10 @@ namespace ts {
}
return emptyObjectType;
}
else if (isTypeAny(attributesType)) {
attributesType = getJsxManagedAttributesFromLocatedAttributes(context, ns, attributesType);
if (isTypeAny(attributesType)) {
// Props is of type 'any' or unknown
return attributesType;
}
@@ -16593,6 +16614,11 @@ namespace ts {
return undefined;
}
function getJsxLibraryManagedAttributes(jsxNamespace: Symbol) {
// JSX.LibraryManagedAttributes [symbol]
return jsxNamespace && getSymbol(jsxNamespace.exports!, JsxNames.LibraryManagedAttributes, SymbolFlags.Type);
}
/// e.g. "props" for React.d.ts,
/// or 'undefined' if ElementAttributesProperty doesn't exist (which means all
/// non-intrinsic elements' attributes type is 'any'),
@@ -28927,6 +28953,7 @@ namespace ts {
export const Element = "Element" as __String;
export const IntrinsicAttributes = "IntrinsicAttributes" as __String;
export const IntrinsicClassAttributes = "IntrinsicClassAttributes" as __String;
export const LibraryManagedAttributes = "LibraryManagedAttributes" as __String;
// tslint:enable variable-name
}
}
@@ -0,0 +1,199 @@
tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(55,12): error TS2322: Type '{ foo: number; }' is not assignable to type 'Defaultize<InferredPropTypes<{ foo: PropTypeChecker<number, false>; bar: PropTypeChecker<ReactNode, false>; baz: PropTypeChecker<string, true>; }>, { foo: number; }>'.
Type '{ foo: number; }' is not assignable to type '{ bar: string | number | ReactComponent<{}, {}> | null | undefined; baz: string; }'.
Property 'bar' is missing in type '{ foo: number; }'.
tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(57,41): error TS2339: Property 'bat' does not exist on type 'Defaultize<InferredPropTypes<{ foo: PropTypeChecker<number, false>; bar: PropTypeChecker<ReactNode, false>; baz: PropTypeChecker<string, true>; }>, { foo: number; }>'.
tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(59,42): error TS2326: Types of property 'baz' are incompatible.
Type 'null' is not assignable to type 'string'.
tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(69,26): error TS2326: Types of property 'foo' are incompatible.
Type 'string' is not assignable to type 'number | null | undefined'.
tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(71,35): error TS2326: Types of property 'bar' are incompatible.
Type 'null' is not assignable to type 'ReactNode'.
tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(80,38): error TS2339: Property 'bar' does not exist on type 'Defaultize<{}, { foo: number; }>'.
tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(81,29): error TS2326: Types of property 'foo' are incompatible.
Type 'string' is not assignable to type 'number | undefined'.
tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(98,12): error TS2322: Type '{ foo: string; }' is not assignable to type 'Defaultize<FooProps & InferredPropTypes<{ foo: PropTypeChecker<string, false>; bar: PropTypeChecker<ReactNode, false>; baz: PropTypeChecker<number, true>; }>, { foo: string; }>'.
Type '{ foo: string; }' is not assignable to type '{ bar: string | number | ReactComponent<{}, {}> | null | undefined; baz: number; }'.
Property 'bar' is missing in type '{ foo: string; }'.
tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(100,56): error TS2339: Property 'bat' does not exist on type 'Defaultize<FooProps & InferredPropTypes<{ foo: PropTypeChecker<string, false>; bar: PropTypeChecker<ReactNode, false>; baz: PropTypeChecker<number, true>; }>, { foo: string; }>'.
tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(102,57): error TS2326: Types of property 'baz' are incompatible.
Type 'null' is not assignable to type 'number'.
tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(111,46): error TS2326: Types of property 'foo' are incompatible.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(112,46): error TS2326: Types of property 'foo' are incompatible.
Type 'null' is not assignable to type 'string'.
tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(113,57): error TS2326: Types of property 'bar' are incompatible.
Type 'null' is not assignable to type 'ReactNode'.
tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(122,58): error TS2339: Property 'bar' does not exist on type 'Defaultize<FooProps, { foo: string; }>'.
tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS2326: Types of property 'foo' are incompatible.
Type 'number' is not assignable to type 'string | undefined'.
==== tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx (15 errors) ====
type Defaultize<TProps, TDefaults> =
& {[K in Extract<keyof TProps, keyof TDefaults>]?: TProps[K]}
& {[K in Exclude<keyof TProps, keyof TDefaults>]: TProps[K]}
& Partial<TDefaults>;
type InferredPropTypes<P> = {[K in keyof P]: P[K] extends PropTypeChecker<infer T, infer U> ? PropTypeChecker<T, U>[typeof checkedType] : {}};
declare const checkedType: unique symbol;
interface PropTypeChecker<U, TRequired = false> {
(props: any, propName: string, componentName: string, location: any, propFullName: string): boolean;
isRequired: PropTypeChecker<U, true>;
[checkedType]: TRequired extends true ? U : U | null | undefined;
}
declare namespace PropTypes {
export const number: PropTypeChecker<number>;
export const string: PropTypeChecker<string>;
export const node: PropTypeChecker<ReactNode>;
}
type ReactNode = string | number | ReactComponent<{}, {}>;
declare class ReactComponent<P={}, S={}> {
constructor(props: P);
props: P & Readonly<{children: ReactNode[]}>;
setState(s: Partial<S>): S;
render(): ReactNode;
}
declare namespace JSX {
interface Element extends ReactComponent {}
interface IntrinsicElements {}
type LibraryManagedAttributes<TComponent, TProps> =
TComponent extends { defaultProps: infer D; propTypes: infer P; }
? Defaultize<TProps & InferredPropTypes<P>, D>
: TComponent extends { defaultProps: infer D }
? Defaultize<TProps, D>
: TComponent extends { propTypes: infer P }
? TProps & InferredPropTypes<P>
: TProps;
}
class Component extends ReactComponent {
static propTypes = {
foo: PropTypes.number,
bar: PropTypes.node,
baz: PropTypes.string.isRequired,
};
static defaultProps = {
foo: 42,
}
}
const a = <Component foo={12} bar="yes" baz="yeah" />;
const b = <Component foo={12} />; // Error, missing required prop bar
~~~~~~~~~
!!! error TS2322: Type '{ foo: number; }' is not assignable to type 'Defaultize<InferredPropTypes<{ foo: PropTypeChecker<number, false>; bar: PropTypeChecker<ReactNode, false>; baz: PropTypeChecker<string, true>; }>, { foo: number; }>'.
!!! error TS2322: Type '{ foo: number; }' is not assignable to type '{ bar: string | number | ReactComponent<{}, {}> | null | undefined; baz: string; }'.
!!! error TS2322: Property 'bar' is missing in type '{ foo: number; }'.
const c = <Component bar="yes" baz="yeah" />;
const d = <Component bar="yes" baz="yo" bat="ohno" />; // Error, baz not a valid prop
~~~~~~~~~~
!!! error TS2339: Property 'bat' does not exist on type 'Defaultize<InferredPropTypes<{ foo: PropTypeChecker<number, false>; bar: PropTypeChecker<ReactNode, false>; baz: PropTypeChecker<string, true>; }>, { foo: number; }>'.
const e = <Component foo={12} bar={null} baz="cool" />; // bar is nullable/undefinable since it's not marked `isRequired`
const f = <Component foo={12} bar="yeah" baz={null} />; // Error, baz is _not_ nullable/undefinable since it's marked `isRequired`
~~~~~~~~~~
!!! error TS2326: Types of property 'baz' are incompatible.
!!! error TS2326: Type 'null' is not assignable to type 'string'.
class JustPropTypes extends ReactComponent {
static propTypes = {
foo: PropTypes.number,
bar: PropTypes.node.isRequired,
};
}
const g = <JustPropTypes foo={12} bar="ok" />;
const h = <JustPropTypes foo="no" />; // error, wrong type
~~~~~~~~
!!! error TS2326: Types of property 'foo' are incompatible.
!!! error TS2326: Type 'string' is not assignable to type 'number | null | undefined'.
const i = <JustPropTypes foo={null} bar="ok" />;
const j = <JustPropTypes foo={12} bar={null} />; // error, bar is required
~~~~~~~~~~
!!! error TS2326: Types of property 'bar' are incompatible.
!!! error TS2326: Type 'null' is not assignable to type 'ReactNode'.
class JustDefaultProps extends ReactComponent {
static defaultProps = {
foo: 42,
};
}
const k = <JustDefaultProps foo={12} />;
const l = <JustDefaultProps foo={12} bar="ok" />; // error, no prop named bar
~~~~~~~~
!!! error TS2339: Property 'bar' does not exist on type 'Defaultize<{}, { foo: number; }>'.
const m = <JustDefaultProps foo="no" />; // error, wrong type
~~~~~~~~
!!! error TS2326: Types of property 'foo' are incompatible.
!!! error TS2326: Type 'string' is not assignable to type 'number | undefined'.
interface FooProps {
foo: string;
}
class BothWithSpecifiedGeneric extends ReactComponent<FooProps> {
static propTypes = {
foo: PropTypes.string,
bar: PropTypes.node,
baz: PropTypes.number.isRequired,
};
static defaultProps = {
foo: "yo",
};
}
const n = <BothWithSpecifiedGeneric foo="fine" bar="yes" baz={12} />;
const o = <BothWithSpecifiedGeneric foo="no" />; // Error, missing required prop bar
~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2322: Type '{ foo: string; }' is not assignable to type 'Defaultize<FooProps & InferredPropTypes<{ foo: PropTypeChecker<string, false>; bar: PropTypeChecker<ReactNode, false>; baz: PropTypeChecker<number, true>; }>, { foo: string; }>'.
!!! error TS2322: Type '{ foo: string; }' is not assignable to type '{ bar: string | number | ReactComponent<{}, {}> | null | undefined; baz: number; }'.
!!! error TS2322: Property 'bar' is missing in type '{ foo: string; }'.
const p = <BothWithSpecifiedGeneric bar="yes" baz={12} />;
const q = <BothWithSpecifiedGeneric bar="yes" baz={12} bat="ohno" />; // Error, baz not a valid prop
~~~~~~~~~~
!!! error TS2339: Property 'bat' does not exist on type 'Defaultize<FooProps & InferredPropTypes<{ foo: PropTypeChecker<string, false>; bar: PropTypeChecker<ReactNode, false>; baz: PropTypeChecker<number, true>; }>, { foo: string; }>'.
const r = <BothWithSpecifiedGeneric foo="no" bar={null} baz={0} />; // bar is nullable/undefinable since it's not marked `isRequired`
const s = <BothWithSpecifiedGeneric foo="eh" bar="yeah" baz={null} />; // Error, baz is _not_ nullable/undefinable since it's marked `isRequired`
~~~~~~~~~~
!!! error TS2326: Types of property 'baz' are incompatible.
!!! error TS2326: Type 'null' is not assignable to type 'number'.
class JustPropTypesWithSpecifiedGeneric extends ReactComponent<FooProps> {
static propTypes = {
foo: PropTypes.string,
bar: PropTypes.node.isRequired,
};
}
const t = <JustPropTypesWithSpecifiedGeneric foo="nice" bar="ok" />;
const u = <JustPropTypesWithSpecifiedGeneric foo={12} />; // error, wrong type
~~~~~~~~
!!! error TS2326: Types of property 'foo' are incompatible.
!!! error TS2326: Type 'number' is not assignable to type 'string'.
const v = <JustPropTypesWithSpecifiedGeneric foo={null} bar="ok" />; // generic overrides propTypes required-ness, null isn't valid
~~~~~~~~~~
!!! error TS2326: Types of property 'foo' are incompatible.
!!! error TS2326: Type 'null' is not assignable to type 'string'.
const w = <JustPropTypesWithSpecifiedGeneric foo="cool" bar={null} />; // error, bar is required
~~~~~~~~~~
!!! error TS2326: Types of property 'bar' are incompatible.
!!! error TS2326: Type 'null' is not assignable to type 'ReactNode'.
class JustDefaultPropsWithSpecifiedGeneric extends ReactComponent<FooProps> {
static defaultProps = {
foo: "no",
};
}
const x = <JustDefaultPropsWithSpecifiedGeneric foo="eh" />;
const y = <JustDefaultPropsWithSpecifiedGeneric foo="no" bar="ok" />; // error, no prop named bar
~~~~~~~~
!!! error TS2339: Property 'bar' does not exist on type 'Defaultize<FooProps, { foo: string; }>'.
const z = <JustDefaultPropsWithSpecifiedGeneric foo={12} />; // error, wrong type
~~~~~~~~
!!! error TS2326: Types of property 'foo' are incompatible.
!!! error TS2326: Type 'number' is not assignable to type 'string | undefined'.
const aa = <JustDefaultPropsWithSpecifiedGeneric />;
@@ -0,0 +1,241 @@
//// [tsxLibraryManagedAttributes.tsx]
type Defaultize<TProps, TDefaults> =
& {[K in Extract<keyof TProps, keyof TDefaults>]?: TProps[K]}
& {[K in Exclude<keyof TProps, keyof TDefaults>]: TProps[K]}
& Partial<TDefaults>;
type InferredPropTypes<P> = {[K in keyof P]: P[K] extends PropTypeChecker<infer T, infer U> ? PropTypeChecker<T, U>[typeof checkedType] : {}};
declare const checkedType: unique symbol;
interface PropTypeChecker<U, TRequired = false> {
(props: any, propName: string, componentName: string, location: any, propFullName: string): boolean;
isRequired: PropTypeChecker<U, true>;
[checkedType]: TRequired extends true ? U : U | null | undefined;
}
declare namespace PropTypes {
export const number: PropTypeChecker<number>;
export const string: PropTypeChecker<string>;
export const node: PropTypeChecker<ReactNode>;
}
type ReactNode = string | number | ReactComponent<{}, {}>;
declare class ReactComponent<P={}, S={}> {
constructor(props: P);
props: P & Readonly<{children: ReactNode[]}>;
setState(s: Partial<S>): S;
render(): ReactNode;
}
declare namespace JSX {
interface Element extends ReactComponent {}
interface IntrinsicElements {}
type LibraryManagedAttributes<TComponent, TProps> =
TComponent extends { defaultProps: infer D; propTypes: infer P; }
? Defaultize<TProps & InferredPropTypes<P>, D>
: TComponent extends { defaultProps: infer D }
? Defaultize<TProps, D>
: TComponent extends { propTypes: infer P }
? TProps & InferredPropTypes<P>
: TProps;
}
class Component extends ReactComponent {
static propTypes = {
foo: PropTypes.number,
bar: PropTypes.node,
baz: PropTypes.string.isRequired,
};
static defaultProps = {
foo: 42,
}
}
const a = <Component foo={12} bar="yes" baz="yeah" />;
const b = <Component foo={12} />; // Error, missing required prop bar
const c = <Component bar="yes" baz="yeah" />;
const d = <Component bar="yes" baz="yo" bat="ohno" />; // Error, baz not a valid prop
const e = <Component foo={12} bar={null} baz="cool" />; // bar is nullable/undefinable since it's not marked `isRequired`
const f = <Component foo={12} bar="yeah" baz={null} />; // Error, baz is _not_ nullable/undefinable since it's marked `isRequired`
class JustPropTypes extends ReactComponent {
static propTypes = {
foo: PropTypes.number,
bar: PropTypes.node.isRequired,
};
}
const g = <JustPropTypes foo={12} bar="ok" />;
const h = <JustPropTypes foo="no" />; // error, wrong type
const i = <JustPropTypes foo={null} bar="ok" />;
const j = <JustPropTypes foo={12} bar={null} />; // error, bar is required
class JustDefaultProps extends ReactComponent {
static defaultProps = {
foo: 42,
};
}
const k = <JustDefaultProps foo={12} />;
const l = <JustDefaultProps foo={12} bar="ok" />; // error, no prop named bar
const m = <JustDefaultProps foo="no" />; // error, wrong type
interface FooProps {
foo: string;
}
class BothWithSpecifiedGeneric extends ReactComponent<FooProps> {
static propTypes = {
foo: PropTypes.string,
bar: PropTypes.node,
baz: PropTypes.number.isRequired,
};
static defaultProps = {
foo: "yo",
};
}
const n = <BothWithSpecifiedGeneric foo="fine" bar="yes" baz={12} />;
const o = <BothWithSpecifiedGeneric foo="no" />; // Error, missing required prop bar
const p = <BothWithSpecifiedGeneric bar="yes" baz={12} />;
const q = <BothWithSpecifiedGeneric bar="yes" baz={12} bat="ohno" />; // Error, baz not a valid prop
const r = <BothWithSpecifiedGeneric foo="no" bar={null} baz={0} />; // bar is nullable/undefinable since it's not marked `isRequired`
const s = <BothWithSpecifiedGeneric foo="eh" bar="yeah" baz={null} />; // Error, baz is _not_ nullable/undefinable since it's marked `isRequired`
class JustPropTypesWithSpecifiedGeneric extends ReactComponent<FooProps> {
static propTypes = {
foo: PropTypes.string,
bar: PropTypes.node.isRequired,
};
}
const t = <JustPropTypesWithSpecifiedGeneric foo="nice" bar="ok" />;
const u = <JustPropTypesWithSpecifiedGeneric foo={12} />; // error, wrong type
const v = <JustPropTypesWithSpecifiedGeneric foo={null} bar="ok" />; // generic overrides propTypes required-ness, null isn't valid
const w = <JustPropTypesWithSpecifiedGeneric foo="cool" bar={null} />; // error, bar is required
class JustDefaultPropsWithSpecifiedGeneric extends ReactComponent<FooProps> {
static defaultProps = {
foo: "no",
};
}
const x = <JustDefaultPropsWithSpecifiedGeneric foo="eh" />;
const y = <JustDefaultPropsWithSpecifiedGeneric foo="no" bar="ok" />; // error, no prop named bar
const z = <JustDefaultPropsWithSpecifiedGeneric foo={12} />; // error, wrong type
const aa = <JustDefaultPropsWithSpecifiedGeneric />;
//// [tsxLibraryManagedAttributes.jsx]
"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 Component = /** @class */ (function (_super) {
__extends(Component, _super);
function Component() {
return _super !== null && _super.apply(this, arguments) || this;
}
Component.propTypes = {
foo: PropTypes.number,
bar: PropTypes.node,
baz: PropTypes.string.isRequired
};
Component.defaultProps = {
foo: 42
};
return Component;
}(ReactComponent));
var a = <Component foo={12} bar="yes" baz="yeah"/>;
var b = <Component foo={12}/>; // Error, missing required prop bar
var c = <Component bar="yes" baz="yeah"/>;
var d = <Component bar="yes" baz="yo" bat="ohno"/>; // Error, baz not a valid prop
var e = <Component foo={12} bar={null} baz="cool"/>; // bar is nullable/undefinable since it's not marked `isRequired`
var f = <Component foo={12} bar="yeah" baz={null}/>; // Error, baz is _not_ nullable/undefinable since it's marked `isRequired`
var JustPropTypes = /** @class */ (function (_super) {
__extends(JustPropTypes, _super);
function JustPropTypes() {
return _super !== null && _super.apply(this, arguments) || this;
}
JustPropTypes.propTypes = {
foo: PropTypes.number,
bar: PropTypes.node.isRequired
};
return JustPropTypes;
}(ReactComponent));
var g = <JustPropTypes foo={12} bar="ok"/>;
var h = <JustPropTypes foo="no"/>; // error, wrong type
var i = <JustPropTypes foo={null} bar="ok"/>;
var j = <JustPropTypes foo={12} bar={null}/>; // error, bar is required
var JustDefaultProps = /** @class */ (function (_super) {
__extends(JustDefaultProps, _super);
function JustDefaultProps() {
return _super !== null && _super.apply(this, arguments) || this;
}
JustDefaultProps.defaultProps = {
foo: 42
};
return JustDefaultProps;
}(ReactComponent));
var k = <JustDefaultProps foo={12}/>;
var l = <JustDefaultProps foo={12} bar="ok"/>; // error, no prop named bar
var m = <JustDefaultProps foo="no"/>; // error, wrong type
var BothWithSpecifiedGeneric = /** @class */ (function (_super) {
__extends(BothWithSpecifiedGeneric, _super);
function BothWithSpecifiedGeneric() {
return _super !== null && _super.apply(this, arguments) || this;
}
BothWithSpecifiedGeneric.propTypes = {
foo: PropTypes.string,
bar: PropTypes.node,
baz: PropTypes.number.isRequired
};
BothWithSpecifiedGeneric.defaultProps = {
foo: "yo"
};
return BothWithSpecifiedGeneric;
}(ReactComponent));
var n = <BothWithSpecifiedGeneric foo="fine" bar="yes" baz={12}/>;
var o = <BothWithSpecifiedGeneric foo="no"/>; // Error, missing required prop bar
var p = <BothWithSpecifiedGeneric bar="yes" baz={12}/>;
var q = <BothWithSpecifiedGeneric bar="yes" baz={12} bat="ohno"/>; // Error, baz not a valid prop
var r = <BothWithSpecifiedGeneric foo="no" bar={null} baz={0}/>; // bar is nullable/undefinable since it's not marked `isRequired`
var s = <BothWithSpecifiedGeneric foo="eh" bar="yeah" baz={null}/>; // Error, baz is _not_ nullable/undefinable since it's marked `isRequired`
var JustPropTypesWithSpecifiedGeneric = /** @class */ (function (_super) {
__extends(JustPropTypesWithSpecifiedGeneric, _super);
function JustPropTypesWithSpecifiedGeneric() {
return _super !== null && _super.apply(this, arguments) || this;
}
JustPropTypesWithSpecifiedGeneric.propTypes = {
foo: PropTypes.string,
bar: PropTypes.node.isRequired
};
return JustPropTypesWithSpecifiedGeneric;
}(ReactComponent));
var t = <JustPropTypesWithSpecifiedGeneric foo="nice" bar="ok"/>;
var u = <JustPropTypesWithSpecifiedGeneric foo={12}/>; // error, wrong type
var v = <JustPropTypesWithSpecifiedGeneric foo={null} bar="ok"/>; // generic overrides propTypes required-ness, null isn't valid
var w = <JustPropTypesWithSpecifiedGeneric foo="cool" bar={null}/>; // error, bar is required
var JustDefaultPropsWithSpecifiedGeneric = /** @class */ (function (_super) {
__extends(JustDefaultPropsWithSpecifiedGeneric, _super);
function JustDefaultPropsWithSpecifiedGeneric() {
return _super !== null && _super.apply(this, arguments) || this;
}
JustDefaultPropsWithSpecifiedGeneric.defaultProps = {
foo: "no"
};
return JustDefaultPropsWithSpecifiedGeneric;
}(ReactComponent));
var x = <JustDefaultPropsWithSpecifiedGeneric foo="eh"/>;
var y = <JustDefaultPropsWithSpecifiedGeneric foo="no" bar="ok"/>; // error, no prop named bar
var z = <JustDefaultPropsWithSpecifiedGeneric foo={12}/>; // error, wrong type
var aa = <JustDefaultPropsWithSpecifiedGeneric />;
@@ -0,0 +1,486 @@
=== tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx ===
type Defaultize<TProps, TDefaults> =
>Defaultize : Symbol(Defaultize, Decl(tsxLibraryManagedAttributes.tsx, 0, 0))
>TProps : Symbol(TProps, Decl(tsxLibraryManagedAttributes.tsx, 0, 16))
>TDefaults : Symbol(TDefaults, Decl(tsxLibraryManagedAttributes.tsx, 0, 23))
& {[K in Extract<keyof TProps, keyof TDefaults>]?: TProps[K]}
>K : Symbol(K, Decl(tsxLibraryManagedAttributes.tsx, 1, 8))
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
>TProps : Symbol(TProps, Decl(tsxLibraryManagedAttributes.tsx, 0, 16))
>TDefaults : Symbol(TDefaults, Decl(tsxLibraryManagedAttributes.tsx, 0, 23))
>TProps : Symbol(TProps, Decl(tsxLibraryManagedAttributes.tsx, 0, 16))
>K : Symbol(K, Decl(tsxLibraryManagedAttributes.tsx, 1, 8))
& {[K in Exclude<keyof TProps, keyof TDefaults>]: TProps[K]}
>K : Symbol(K, Decl(tsxLibraryManagedAttributes.tsx, 2, 8))
>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --))
>TProps : Symbol(TProps, Decl(tsxLibraryManagedAttributes.tsx, 0, 16))
>TDefaults : Symbol(TDefaults, Decl(tsxLibraryManagedAttributes.tsx, 0, 23))
>TProps : Symbol(TProps, Decl(tsxLibraryManagedAttributes.tsx, 0, 16))
>K : Symbol(K, Decl(tsxLibraryManagedAttributes.tsx, 2, 8))
& Partial<TDefaults>;
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
>TDefaults : Symbol(TDefaults, Decl(tsxLibraryManagedAttributes.tsx, 0, 23))
type InferredPropTypes<P> = {[K in keyof P]: P[K] extends PropTypeChecker<infer T, infer U> ? PropTypeChecker<T, U>[typeof checkedType] : {}};
>InferredPropTypes : Symbol(InferredPropTypes, Decl(tsxLibraryManagedAttributes.tsx, 3, 25))
>P : Symbol(P, Decl(tsxLibraryManagedAttributes.tsx, 5, 23))
>K : Symbol(K, Decl(tsxLibraryManagedAttributes.tsx, 5, 30))
>P : Symbol(P, Decl(tsxLibraryManagedAttributes.tsx, 5, 23))
>P : Symbol(P, Decl(tsxLibraryManagedAttributes.tsx, 5, 23))
>K : Symbol(K, Decl(tsxLibraryManagedAttributes.tsx, 5, 30))
>PropTypeChecker : Symbol(PropTypeChecker, Decl(tsxLibraryManagedAttributes.tsx, 7, 41))
>T : Symbol(T, Decl(tsxLibraryManagedAttributes.tsx, 5, 79))
>U : Symbol(U, Decl(tsxLibraryManagedAttributes.tsx, 5, 88))
>PropTypeChecker : Symbol(PropTypeChecker, Decl(tsxLibraryManagedAttributes.tsx, 7, 41))
>T : Symbol(T, Decl(tsxLibraryManagedAttributes.tsx, 5, 79))
>U : Symbol(U, Decl(tsxLibraryManagedAttributes.tsx, 5, 88))
>checkedType : Symbol(checkedType, Decl(tsxLibraryManagedAttributes.tsx, 7, 13))
declare const checkedType: unique symbol;
>checkedType : Symbol(checkedType, Decl(tsxLibraryManagedAttributes.tsx, 7, 13))
interface PropTypeChecker<U, TRequired = false> {
>PropTypeChecker : Symbol(PropTypeChecker, Decl(tsxLibraryManagedAttributes.tsx, 7, 41))
>U : Symbol(U, Decl(tsxLibraryManagedAttributes.tsx, 8, 26))
>TRequired : Symbol(TRequired, Decl(tsxLibraryManagedAttributes.tsx, 8, 28))
(props: any, propName: string, componentName: string, location: any, propFullName: string): boolean;
>props : Symbol(props, Decl(tsxLibraryManagedAttributes.tsx, 9, 5))
>propName : Symbol(propName, Decl(tsxLibraryManagedAttributes.tsx, 9, 16))
>componentName : Symbol(componentName, Decl(tsxLibraryManagedAttributes.tsx, 9, 34))
>location : Symbol(location, Decl(tsxLibraryManagedAttributes.tsx, 9, 57))
>propFullName : Symbol(propFullName, Decl(tsxLibraryManagedAttributes.tsx, 9, 72))
isRequired: PropTypeChecker<U, true>;
>isRequired : Symbol(PropTypeChecker.isRequired, Decl(tsxLibraryManagedAttributes.tsx, 9, 104))
>PropTypeChecker : Symbol(PropTypeChecker, Decl(tsxLibraryManagedAttributes.tsx, 7, 41))
>U : Symbol(U, Decl(tsxLibraryManagedAttributes.tsx, 8, 26))
[checkedType]: TRequired extends true ? U : U | null | undefined;
>[checkedType] : Symbol(PropTypeChecker[checkedType], Decl(tsxLibraryManagedAttributes.tsx, 10, 41))
>checkedType : Symbol(checkedType, Decl(tsxLibraryManagedAttributes.tsx, 7, 13))
>TRequired : Symbol(TRequired, Decl(tsxLibraryManagedAttributes.tsx, 8, 28))
>U : Symbol(U, Decl(tsxLibraryManagedAttributes.tsx, 8, 26))
>U : Symbol(U, Decl(tsxLibraryManagedAttributes.tsx, 8, 26))
}
declare namespace PropTypes {
>PropTypes : Symbol(PropTypes, Decl(tsxLibraryManagedAttributes.tsx, 12, 1))
export const number: PropTypeChecker<number>;
>number : Symbol(number, Decl(tsxLibraryManagedAttributes.tsx, 15, 16))
>PropTypeChecker : Symbol(PropTypeChecker, Decl(tsxLibraryManagedAttributes.tsx, 7, 41))
export const string: PropTypeChecker<string>;
>string : Symbol(string, Decl(tsxLibraryManagedAttributes.tsx, 16, 16))
>PropTypeChecker : Symbol(PropTypeChecker, Decl(tsxLibraryManagedAttributes.tsx, 7, 41))
export const node: PropTypeChecker<ReactNode>;
>node : Symbol(node, Decl(tsxLibraryManagedAttributes.tsx, 17, 16))
>PropTypeChecker : Symbol(PropTypeChecker, Decl(tsxLibraryManagedAttributes.tsx, 7, 41))
>ReactNode : Symbol(ReactNode, Decl(tsxLibraryManagedAttributes.tsx, 18, 1))
}
type ReactNode = string | number | ReactComponent<{}, {}>;
>ReactNode : Symbol(ReactNode, Decl(tsxLibraryManagedAttributes.tsx, 18, 1))
>ReactComponent : Symbol(ReactComponent, Decl(tsxLibraryManagedAttributes.tsx, 20, 58))
declare class ReactComponent<P={}, S={}> {
>ReactComponent : Symbol(ReactComponent, Decl(tsxLibraryManagedAttributes.tsx, 20, 58))
>P : Symbol(P, Decl(tsxLibraryManagedAttributes.tsx, 22, 29))
>S : Symbol(S, Decl(tsxLibraryManagedAttributes.tsx, 22, 34))
constructor(props: P);
>props : Symbol(props, Decl(tsxLibraryManagedAttributes.tsx, 23, 16))
>P : Symbol(P, Decl(tsxLibraryManagedAttributes.tsx, 22, 29))
props: P & Readonly<{children: ReactNode[]}>;
>props : Symbol(ReactComponent.props, Decl(tsxLibraryManagedAttributes.tsx, 23, 26))
>P : Symbol(P, Decl(tsxLibraryManagedAttributes.tsx, 22, 29))
>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --))
>children : Symbol(children, Decl(tsxLibraryManagedAttributes.tsx, 24, 25))
>ReactNode : Symbol(ReactNode, Decl(tsxLibraryManagedAttributes.tsx, 18, 1))
setState(s: Partial<S>): S;
>setState : Symbol(ReactComponent.setState, Decl(tsxLibraryManagedAttributes.tsx, 24, 49))
>s : Symbol(s, Decl(tsxLibraryManagedAttributes.tsx, 25, 13))
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
>S : Symbol(S, Decl(tsxLibraryManagedAttributes.tsx, 22, 34))
>S : Symbol(S, Decl(tsxLibraryManagedAttributes.tsx, 22, 34))
render(): ReactNode;
>render : Symbol(ReactComponent.render, Decl(tsxLibraryManagedAttributes.tsx, 25, 31))
>ReactNode : Symbol(ReactNode, Decl(tsxLibraryManagedAttributes.tsx, 18, 1))
}
declare namespace JSX {
>JSX : Symbol(JSX, Decl(tsxLibraryManagedAttributes.tsx, 27, 1))
interface Element extends ReactComponent {}
>Element : Symbol(Element, Decl(tsxLibraryManagedAttributes.tsx, 29, 23))
>ReactComponent : Symbol(ReactComponent, Decl(tsxLibraryManagedAttributes.tsx, 20, 58))
interface IntrinsicElements {}
>IntrinsicElements : Symbol(IntrinsicElements, Decl(tsxLibraryManagedAttributes.tsx, 30, 47))
type LibraryManagedAttributes<TComponent, TProps> =
>LibraryManagedAttributes : Symbol(LibraryManagedAttributes, Decl(tsxLibraryManagedAttributes.tsx, 31, 34))
>TComponent : Symbol(TComponent, Decl(tsxLibraryManagedAttributes.tsx, 32, 34))
>TProps : Symbol(TProps, Decl(tsxLibraryManagedAttributes.tsx, 32, 45))
TComponent extends { defaultProps: infer D; propTypes: infer P; }
>TComponent : Symbol(TComponent, Decl(tsxLibraryManagedAttributes.tsx, 32, 34))
>defaultProps : Symbol(defaultProps, Decl(tsxLibraryManagedAttributes.tsx, 33, 28))
>D : Symbol(D, Decl(tsxLibraryManagedAttributes.tsx, 33, 48))
>propTypes : Symbol(propTypes, Decl(tsxLibraryManagedAttributes.tsx, 33, 51))
>P : Symbol(P, Decl(tsxLibraryManagedAttributes.tsx, 33, 68))
? Defaultize<TProps & InferredPropTypes<P>, D>
>Defaultize : Symbol(Defaultize, Decl(tsxLibraryManagedAttributes.tsx, 0, 0))
>TProps : Symbol(TProps, Decl(tsxLibraryManagedAttributes.tsx, 32, 45))
>InferredPropTypes : Symbol(InferredPropTypes, Decl(tsxLibraryManagedAttributes.tsx, 3, 25))
>P : Symbol(P, Decl(tsxLibraryManagedAttributes.tsx, 33, 68))
>D : Symbol(D, Decl(tsxLibraryManagedAttributes.tsx, 33, 48))
: TComponent extends { defaultProps: infer D }
>TComponent : Symbol(TComponent, Decl(tsxLibraryManagedAttributes.tsx, 32, 34))
>defaultProps : Symbol(defaultProps, Decl(tsxLibraryManagedAttributes.tsx, 35, 34))
>D : Symbol(D, Decl(tsxLibraryManagedAttributes.tsx, 35, 54))
? Defaultize<TProps, D>
>Defaultize : Symbol(Defaultize, Decl(tsxLibraryManagedAttributes.tsx, 0, 0))
>TProps : Symbol(TProps, Decl(tsxLibraryManagedAttributes.tsx, 32, 45))
>D : Symbol(D, Decl(tsxLibraryManagedAttributes.tsx, 35, 54))
: TComponent extends { propTypes: infer P }
>TComponent : Symbol(TComponent, Decl(tsxLibraryManagedAttributes.tsx, 32, 34))
>propTypes : Symbol(propTypes, Decl(tsxLibraryManagedAttributes.tsx, 37, 38))
>P : Symbol(P, Decl(tsxLibraryManagedAttributes.tsx, 37, 55))
? TProps & InferredPropTypes<P>
>TProps : Symbol(TProps, Decl(tsxLibraryManagedAttributes.tsx, 32, 45))
>InferredPropTypes : Symbol(InferredPropTypes, Decl(tsxLibraryManagedAttributes.tsx, 3, 25))
>P : Symbol(P, Decl(tsxLibraryManagedAttributes.tsx, 37, 55))
: TProps;
>TProps : Symbol(TProps, Decl(tsxLibraryManagedAttributes.tsx, 32, 45))
}
class Component extends ReactComponent {
>Component : Symbol(Component, Decl(tsxLibraryManagedAttributes.tsx, 40, 1))
>ReactComponent : Symbol(ReactComponent, Decl(tsxLibraryManagedAttributes.tsx, 20, 58))
static propTypes = {
>propTypes : Symbol(Component.propTypes, Decl(tsxLibraryManagedAttributes.tsx, 42, 40))
foo: PropTypes.number,
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 43, 24))
>PropTypes.number : Symbol(PropTypes.number, Decl(tsxLibraryManagedAttributes.tsx, 15, 16))
>PropTypes : Symbol(PropTypes, Decl(tsxLibraryManagedAttributes.tsx, 12, 1))
>number : Symbol(PropTypes.number, Decl(tsxLibraryManagedAttributes.tsx, 15, 16))
bar: PropTypes.node,
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 44, 30))
>PropTypes.node : Symbol(PropTypes.node, Decl(tsxLibraryManagedAttributes.tsx, 17, 16))
>PropTypes : Symbol(PropTypes, Decl(tsxLibraryManagedAttributes.tsx, 12, 1))
>node : Symbol(PropTypes.node, Decl(tsxLibraryManagedAttributes.tsx, 17, 16))
baz: PropTypes.string.isRequired,
>baz : Symbol(baz, Decl(tsxLibraryManagedAttributes.tsx, 45, 28))
>PropTypes.string.isRequired : Symbol(PropTypeChecker.isRequired, Decl(tsxLibraryManagedAttributes.tsx, 9, 104))
>PropTypes.string : Symbol(PropTypes.string, Decl(tsxLibraryManagedAttributes.tsx, 16, 16))
>PropTypes : Symbol(PropTypes, Decl(tsxLibraryManagedAttributes.tsx, 12, 1))
>string : Symbol(PropTypes.string, Decl(tsxLibraryManagedAttributes.tsx, 16, 16))
>isRequired : Symbol(PropTypeChecker.isRequired, Decl(tsxLibraryManagedAttributes.tsx, 9, 104))
};
static defaultProps = {
>defaultProps : Symbol(Component.defaultProps, Decl(tsxLibraryManagedAttributes.tsx, 47, 6))
foo: 42,
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 48, 27))
}
}
const a = <Component foo={12} bar="yes" baz="yeah" />;
>a : Symbol(a, Decl(tsxLibraryManagedAttributes.tsx, 53, 5))
>Component : Symbol(Component, Decl(tsxLibraryManagedAttributes.tsx, 40, 1))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 53, 20))
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 53, 29))
>baz : Symbol(baz, Decl(tsxLibraryManagedAttributes.tsx, 53, 39))
const b = <Component foo={12} />; // Error, missing required prop bar
>b : Symbol(b, Decl(tsxLibraryManagedAttributes.tsx, 54, 5))
>Component : Symbol(Component, Decl(tsxLibraryManagedAttributes.tsx, 40, 1))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 54, 20))
const c = <Component bar="yes" baz="yeah" />;
>c : Symbol(c, Decl(tsxLibraryManagedAttributes.tsx, 55, 5))
>Component : Symbol(Component, Decl(tsxLibraryManagedAttributes.tsx, 40, 1))
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 55, 20))
>baz : Symbol(baz, Decl(tsxLibraryManagedAttributes.tsx, 55, 30))
const d = <Component bar="yes" baz="yo" bat="ohno" />; // Error, baz not a valid prop
>d : Symbol(d, Decl(tsxLibraryManagedAttributes.tsx, 56, 5))
>Component : Symbol(Component, Decl(tsxLibraryManagedAttributes.tsx, 40, 1))
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 56, 20))
>baz : Symbol(baz, Decl(tsxLibraryManagedAttributes.tsx, 56, 30))
>bat : Symbol(bat, Decl(tsxLibraryManagedAttributes.tsx, 56, 39))
const e = <Component foo={12} bar={null} baz="cool" />; // bar is nullable/undefinable since it's not marked `isRequired`
>e : Symbol(e, Decl(tsxLibraryManagedAttributes.tsx, 57, 5))
>Component : Symbol(Component, Decl(tsxLibraryManagedAttributes.tsx, 40, 1))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 57, 20))
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 57, 29))
>baz : Symbol(baz, Decl(tsxLibraryManagedAttributes.tsx, 57, 40))
const f = <Component foo={12} bar="yeah" baz={null} />; // Error, baz is _not_ nullable/undefinable since it's marked `isRequired`
>f : Symbol(f, Decl(tsxLibraryManagedAttributes.tsx, 58, 5))
>Component : Symbol(Component, Decl(tsxLibraryManagedAttributes.tsx, 40, 1))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 58, 20))
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 58, 29))
>baz : Symbol(baz, Decl(tsxLibraryManagedAttributes.tsx, 58, 40))
class JustPropTypes extends ReactComponent {
>JustPropTypes : Symbol(JustPropTypes, Decl(tsxLibraryManagedAttributes.tsx, 58, 55))
>ReactComponent : Symbol(ReactComponent, Decl(tsxLibraryManagedAttributes.tsx, 20, 58))
static propTypes = {
>propTypes : Symbol(JustPropTypes.propTypes, Decl(tsxLibraryManagedAttributes.tsx, 60, 44))
foo: PropTypes.number,
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 61, 24))
>PropTypes.number : Symbol(PropTypes.number, Decl(tsxLibraryManagedAttributes.tsx, 15, 16))
>PropTypes : Symbol(PropTypes, Decl(tsxLibraryManagedAttributes.tsx, 12, 1))
>number : Symbol(PropTypes.number, Decl(tsxLibraryManagedAttributes.tsx, 15, 16))
bar: PropTypes.node.isRequired,
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 62, 30))
>PropTypes.node.isRequired : Symbol(PropTypeChecker.isRequired, Decl(tsxLibraryManagedAttributes.tsx, 9, 104))
>PropTypes.node : Symbol(PropTypes.node, Decl(tsxLibraryManagedAttributes.tsx, 17, 16))
>PropTypes : Symbol(PropTypes, Decl(tsxLibraryManagedAttributes.tsx, 12, 1))
>node : Symbol(PropTypes.node, Decl(tsxLibraryManagedAttributes.tsx, 17, 16))
>isRequired : Symbol(PropTypeChecker.isRequired, Decl(tsxLibraryManagedAttributes.tsx, 9, 104))
};
}
const g = <JustPropTypes foo={12} bar="ok" />;
>g : Symbol(g, Decl(tsxLibraryManagedAttributes.tsx, 67, 5))
>JustPropTypes : Symbol(JustPropTypes, Decl(tsxLibraryManagedAttributes.tsx, 58, 55))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 67, 24))
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 67, 33))
const h = <JustPropTypes foo="no" />; // error, wrong type
>h : Symbol(h, Decl(tsxLibraryManagedAttributes.tsx, 68, 5))
>JustPropTypes : Symbol(JustPropTypes, Decl(tsxLibraryManagedAttributes.tsx, 58, 55))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 68, 24))
const i = <JustPropTypes foo={null} bar="ok" />;
>i : Symbol(i, Decl(tsxLibraryManagedAttributes.tsx, 69, 5))
>JustPropTypes : Symbol(JustPropTypes, Decl(tsxLibraryManagedAttributes.tsx, 58, 55))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 69, 24))
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 69, 35))
const j = <JustPropTypes foo={12} bar={null} />; // error, bar is required
>j : Symbol(j, Decl(tsxLibraryManagedAttributes.tsx, 70, 5))
>JustPropTypes : Symbol(JustPropTypes, Decl(tsxLibraryManagedAttributes.tsx, 58, 55))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 70, 24))
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 70, 33))
class JustDefaultProps extends ReactComponent {
>JustDefaultProps : Symbol(JustDefaultProps, Decl(tsxLibraryManagedAttributes.tsx, 70, 48))
>ReactComponent : Symbol(ReactComponent, Decl(tsxLibraryManagedAttributes.tsx, 20, 58))
static defaultProps = {
>defaultProps : Symbol(JustDefaultProps.defaultProps, Decl(tsxLibraryManagedAttributes.tsx, 72, 47))
foo: 42,
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 73, 27))
};
}
const k = <JustDefaultProps foo={12} />;
>k : Symbol(k, Decl(tsxLibraryManagedAttributes.tsx, 78, 5))
>JustDefaultProps : Symbol(JustDefaultProps, Decl(tsxLibraryManagedAttributes.tsx, 70, 48))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 78, 27))
const l = <JustDefaultProps foo={12} bar="ok" />; // error, no prop named bar
>l : Symbol(l, Decl(tsxLibraryManagedAttributes.tsx, 79, 5))
>JustDefaultProps : Symbol(JustDefaultProps, Decl(tsxLibraryManagedAttributes.tsx, 70, 48))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 79, 27))
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 79, 36))
const m = <JustDefaultProps foo="no" />; // error, wrong type
>m : Symbol(m, Decl(tsxLibraryManagedAttributes.tsx, 80, 5))
>JustDefaultProps : Symbol(JustDefaultProps, Decl(tsxLibraryManagedAttributes.tsx, 70, 48))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 80, 27))
interface FooProps {
>FooProps : Symbol(FooProps, Decl(tsxLibraryManagedAttributes.tsx, 80, 40))
foo: string;
>foo : Symbol(FooProps.foo, Decl(tsxLibraryManagedAttributes.tsx, 82, 20))
}
class BothWithSpecifiedGeneric extends ReactComponent<FooProps> {
>BothWithSpecifiedGeneric : Symbol(BothWithSpecifiedGeneric, Decl(tsxLibraryManagedAttributes.tsx, 84, 1))
>ReactComponent : Symbol(ReactComponent, Decl(tsxLibraryManagedAttributes.tsx, 20, 58))
>FooProps : Symbol(FooProps, Decl(tsxLibraryManagedAttributes.tsx, 80, 40))
static propTypes = {
>propTypes : Symbol(BothWithSpecifiedGeneric.propTypes, Decl(tsxLibraryManagedAttributes.tsx, 86, 65))
foo: PropTypes.string,
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 87, 24))
>PropTypes.string : Symbol(PropTypes.string, Decl(tsxLibraryManagedAttributes.tsx, 16, 16))
>PropTypes : Symbol(PropTypes, Decl(tsxLibraryManagedAttributes.tsx, 12, 1))
>string : Symbol(PropTypes.string, Decl(tsxLibraryManagedAttributes.tsx, 16, 16))
bar: PropTypes.node,
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 88, 30))
>PropTypes.node : Symbol(PropTypes.node, Decl(tsxLibraryManagedAttributes.tsx, 17, 16))
>PropTypes : Symbol(PropTypes, Decl(tsxLibraryManagedAttributes.tsx, 12, 1))
>node : Symbol(PropTypes.node, Decl(tsxLibraryManagedAttributes.tsx, 17, 16))
baz: PropTypes.number.isRequired,
>baz : Symbol(baz, Decl(tsxLibraryManagedAttributes.tsx, 89, 28))
>PropTypes.number.isRequired : Symbol(PropTypeChecker.isRequired, Decl(tsxLibraryManagedAttributes.tsx, 9, 104))
>PropTypes.number : Symbol(PropTypes.number, Decl(tsxLibraryManagedAttributes.tsx, 15, 16))
>PropTypes : Symbol(PropTypes, Decl(tsxLibraryManagedAttributes.tsx, 12, 1))
>number : Symbol(PropTypes.number, Decl(tsxLibraryManagedAttributes.tsx, 15, 16))
>isRequired : Symbol(PropTypeChecker.isRequired, Decl(tsxLibraryManagedAttributes.tsx, 9, 104))
};
static defaultProps = {
>defaultProps : Symbol(BothWithSpecifiedGeneric.defaultProps, Decl(tsxLibraryManagedAttributes.tsx, 91, 6))
foo: "yo",
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 92, 27))
};
}
const n = <BothWithSpecifiedGeneric foo="fine" bar="yes" baz={12} />;
>n : Symbol(n, Decl(tsxLibraryManagedAttributes.tsx, 96, 5))
>BothWithSpecifiedGeneric : Symbol(BothWithSpecifiedGeneric, Decl(tsxLibraryManagedAttributes.tsx, 84, 1))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 96, 35))
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 96, 46))
>baz : Symbol(baz, Decl(tsxLibraryManagedAttributes.tsx, 96, 56))
const o = <BothWithSpecifiedGeneric foo="no" />; // Error, missing required prop bar
>o : Symbol(o, Decl(tsxLibraryManagedAttributes.tsx, 97, 5))
>BothWithSpecifiedGeneric : Symbol(BothWithSpecifiedGeneric, Decl(tsxLibraryManagedAttributes.tsx, 84, 1))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 97, 35))
const p = <BothWithSpecifiedGeneric bar="yes" baz={12} />;
>p : Symbol(p, Decl(tsxLibraryManagedAttributes.tsx, 98, 5))
>BothWithSpecifiedGeneric : Symbol(BothWithSpecifiedGeneric, Decl(tsxLibraryManagedAttributes.tsx, 84, 1))
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 98, 35))
>baz : Symbol(baz, Decl(tsxLibraryManagedAttributes.tsx, 98, 45))
const q = <BothWithSpecifiedGeneric bar="yes" baz={12} bat="ohno" />; // Error, baz not a valid prop
>q : Symbol(q, Decl(tsxLibraryManagedAttributes.tsx, 99, 5))
>BothWithSpecifiedGeneric : Symbol(BothWithSpecifiedGeneric, Decl(tsxLibraryManagedAttributes.tsx, 84, 1))
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 99, 35))
>baz : Symbol(baz, Decl(tsxLibraryManagedAttributes.tsx, 99, 45))
>bat : Symbol(bat, Decl(tsxLibraryManagedAttributes.tsx, 99, 54))
const r = <BothWithSpecifiedGeneric foo="no" bar={null} baz={0} />; // bar is nullable/undefinable since it's not marked `isRequired`
>r : Symbol(r, Decl(tsxLibraryManagedAttributes.tsx, 100, 5))
>BothWithSpecifiedGeneric : Symbol(BothWithSpecifiedGeneric, Decl(tsxLibraryManagedAttributes.tsx, 84, 1))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 100, 35))
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 100, 44))
>baz : Symbol(baz, Decl(tsxLibraryManagedAttributes.tsx, 100, 55))
const s = <BothWithSpecifiedGeneric foo="eh" bar="yeah" baz={null} />; // Error, baz is _not_ nullable/undefinable since it's marked `isRequired`
>s : Symbol(s, Decl(tsxLibraryManagedAttributes.tsx, 101, 5))
>BothWithSpecifiedGeneric : Symbol(BothWithSpecifiedGeneric, Decl(tsxLibraryManagedAttributes.tsx, 84, 1))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 101, 35))
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 101, 44))
>baz : Symbol(baz, Decl(tsxLibraryManagedAttributes.tsx, 101, 55))
class JustPropTypesWithSpecifiedGeneric extends ReactComponent<FooProps> {
>JustPropTypesWithSpecifiedGeneric : Symbol(JustPropTypesWithSpecifiedGeneric, Decl(tsxLibraryManagedAttributes.tsx, 101, 70))
>ReactComponent : Symbol(ReactComponent, Decl(tsxLibraryManagedAttributes.tsx, 20, 58))
>FooProps : Symbol(FooProps, Decl(tsxLibraryManagedAttributes.tsx, 80, 40))
static propTypes = {
>propTypes : Symbol(JustPropTypesWithSpecifiedGeneric.propTypes, Decl(tsxLibraryManagedAttributes.tsx, 103, 74))
foo: PropTypes.string,
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 104, 24))
>PropTypes.string : Symbol(PropTypes.string, Decl(tsxLibraryManagedAttributes.tsx, 16, 16))
>PropTypes : Symbol(PropTypes, Decl(tsxLibraryManagedAttributes.tsx, 12, 1))
>string : Symbol(PropTypes.string, Decl(tsxLibraryManagedAttributes.tsx, 16, 16))
bar: PropTypes.node.isRequired,
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 105, 30))
>PropTypes.node.isRequired : Symbol(PropTypeChecker.isRequired, Decl(tsxLibraryManagedAttributes.tsx, 9, 104))
>PropTypes.node : Symbol(PropTypes.node, Decl(tsxLibraryManagedAttributes.tsx, 17, 16))
>PropTypes : Symbol(PropTypes, Decl(tsxLibraryManagedAttributes.tsx, 12, 1))
>node : Symbol(PropTypes.node, Decl(tsxLibraryManagedAttributes.tsx, 17, 16))
>isRequired : Symbol(PropTypeChecker.isRequired, Decl(tsxLibraryManagedAttributes.tsx, 9, 104))
};
}
const t = <JustPropTypesWithSpecifiedGeneric foo="nice" bar="ok" />;
>t : Symbol(t, Decl(tsxLibraryManagedAttributes.tsx, 109, 5))
>JustPropTypesWithSpecifiedGeneric : Symbol(JustPropTypesWithSpecifiedGeneric, Decl(tsxLibraryManagedAttributes.tsx, 101, 70))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 109, 44))
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 109, 55))
const u = <JustPropTypesWithSpecifiedGeneric foo={12} />; // error, wrong type
>u : Symbol(u, Decl(tsxLibraryManagedAttributes.tsx, 110, 5))
>JustPropTypesWithSpecifiedGeneric : Symbol(JustPropTypesWithSpecifiedGeneric, Decl(tsxLibraryManagedAttributes.tsx, 101, 70))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 110, 44))
const v = <JustPropTypesWithSpecifiedGeneric foo={null} bar="ok" />; // generic overrides propTypes required-ness, null isn't valid
>v : Symbol(v, Decl(tsxLibraryManagedAttributes.tsx, 111, 5))
>JustPropTypesWithSpecifiedGeneric : Symbol(JustPropTypesWithSpecifiedGeneric, Decl(tsxLibraryManagedAttributes.tsx, 101, 70))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 111, 44))
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 111, 55))
const w = <JustPropTypesWithSpecifiedGeneric foo="cool" bar={null} />; // error, bar is required
>w : Symbol(w, Decl(tsxLibraryManagedAttributes.tsx, 112, 5))
>JustPropTypesWithSpecifiedGeneric : Symbol(JustPropTypesWithSpecifiedGeneric, Decl(tsxLibraryManagedAttributes.tsx, 101, 70))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 112, 44))
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 112, 55))
class JustDefaultPropsWithSpecifiedGeneric extends ReactComponent<FooProps> {
>JustDefaultPropsWithSpecifiedGeneric : Symbol(JustDefaultPropsWithSpecifiedGeneric, Decl(tsxLibraryManagedAttributes.tsx, 112, 70))
>ReactComponent : Symbol(ReactComponent, Decl(tsxLibraryManagedAttributes.tsx, 20, 58))
>FooProps : Symbol(FooProps, Decl(tsxLibraryManagedAttributes.tsx, 80, 40))
static defaultProps = {
>defaultProps : Symbol(JustDefaultPropsWithSpecifiedGeneric.defaultProps, Decl(tsxLibraryManagedAttributes.tsx, 114, 77))
foo: "no",
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 115, 27))
};
}
const x = <JustDefaultPropsWithSpecifiedGeneric foo="eh" />;
>x : Symbol(x, Decl(tsxLibraryManagedAttributes.tsx, 120, 5))
>JustDefaultPropsWithSpecifiedGeneric : Symbol(JustDefaultPropsWithSpecifiedGeneric, Decl(tsxLibraryManagedAttributes.tsx, 112, 70))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 120, 47))
const y = <JustDefaultPropsWithSpecifiedGeneric foo="no" bar="ok" />; // error, no prop named bar
>y : Symbol(y, Decl(tsxLibraryManagedAttributes.tsx, 121, 5))
>JustDefaultPropsWithSpecifiedGeneric : Symbol(JustDefaultPropsWithSpecifiedGeneric, Decl(tsxLibraryManagedAttributes.tsx, 112, 70))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 121, 47))
>bar : Symbol(bar, Decl(tsxLibraryManagedAttributes.tsx, 121, 56))
const z = <JustDefaultPropsWithSpecifiedGeneric foo={12} />; // error, wrong type
>z : Symbol(z, Decl(tsxLibraryManagedAttributes.tsx, 122, 5))
>JustDefaultPropsWithSpecifiedGeneric : Symbol(JustDefaultPropsWithSpecifiedGeneric, Decl(tsxLibraryManagedAttributes.tsx, 112, 70))
>foo : Symbol(foo, Decl(tsxLibraryManagedAttributes.tsx, 122, 47))
const aa = <JustDefaultPropsWithSpecifiedGeneric />;
>aa : Symbol(aa, Decl(tsxLibraryManagedAttributes.tsx, 123, 5))
>JustDefaultPropsWithSpecifiedGeneric : Symbol(JustDefaultPropsWithSpecifiedGeneric, Decl(tsxLibraryManagedAttributes.tsx, 112, 70))
@@ -0,0 +1,551 @@
=== tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx ===
type Defaultize<TProps, TDefaults> =
>Defaultize : Defaultize<TProps, TDefaults>
>TProps : TProps
>TDefaults : TDefaults
& {[K in Extract<keyof TProps, keyof TDefaults>]?: TProps[K]}
>K : K
>Extract : Extract<T, U>
>TProps : TProps
>TDefaults : TDefaults
>TProps : TProps
>K : K
& {[K in Exclude<keyof TProps, keyof TDefaults>]: TProps[K]}
>K : K
>Exclude : Exclude<T, U>
>TProps : TProps
>TDefaults : TDefaults
>TProps : TProps
>K : K
& Partial<TDefaults>;
>Partial : Partial<T>
>TDefaults : TDefaults
type InferredPropTypes<P> = {[K in keyof P]: P[K] extends PropTypeChecker<infer T, infer U> ? PropTypeChecker<T, U>[typeof checkedType] : {}};
>InferredPropTypes : InferredPropTypes<P>
>P : P
>K : K
>P : P
>P : P
>K : K
>PropTypeChecker : PropTypeChecker<U, TRequired>
>T : T
>U : U
>PropTypeChecker : PropTypeChecker<U, TRequired>
>T : T
>U : U
>checkedType : unique symbol
declare const checkedType: unique symbol;
>checkedType : unique symbol
interface PropTypeChecker<U, TRequired = false> {
>PropTypeChecker : PropTypeChecker<U, TRequired>
>U : U
>TRequired : TRequired
>false : false
(props: any, propName: string, componentName: string, location: any, propFullName: string): boolean;
>props : any
>propName : string
>componentName : string
>location : any
>propFullName : string
isRequired: PropTypeChecker<U, true>;
>isRequired : PropTypeChecker<U, true>
>PropTypeChecker : PropTypeChecker<U, TRequired>
>U : U
>true : true
[checkedType]: TRequired extends true ? U : U | null | undefined;
>[checkedType] : TRequired extends true ? U : U | null | undefined
>checkedType : unique symbol
>TRequired : TRequired
>true : true
>U : U
>U : U
>null : null
}
declare namespace PropTypes {
>PropTypes : typeof PropTypes
export const number: PropTypeChecker<number>;
>number : PropTypeChecker<number, false>
>PropTypeChecker : PropTypeChecker<U, TRequired>
export const string: PropTypeChecker<string>;
>string : PropTypeChecker<string, false>
>PropTypeChecker : PropTypeChecker<U, TRequired>
export const node: PropTypeChecker<ReactNode>;
>node : PropTypeChecker<ReactNode, false>
>PropTypeChecker : PropTypeChecker<U, TRequired>
>ReactNode : ReactNode
}
type ReactNode = string | number | ReactComponent<{}, {}>;
>ReactNode : ReactNode
>ReactComponent : ReactComponent<P, S>
declare class ReactComponent<P={}, S={}> {
>ReactComponent : ReactComponent<P, S>
>P : P
>S : S
constructor(props: P);
>props : P
>P : P
props: P & Readonly<{children: ReactNode[]}>;
>props : P & Readonly<{ children: ReactNode[]; }>
>P : P
>Readonly : Readonly<T>
>children : ReactNode[]
>ReactNode : ReactNode
setState(s: Partial<S>): S;
>setState : (s: Partial<S>) => S
>s : Partial<S>
>Partial : Partial<T>
>S : S
>S : S
render(): ReactNode;
>render : () => ReactNode
>ReactNode : ReactNode
}
declare namespace JSX {
>JSX : any
interface Element extends ReactComponent {}
>Element : Element
>ReactComponent : ReactComponent<P, S>
interface IntrinsicElements {}
>IntrinsicElements : IntrinsicElements
type LibraryManagedAttributes<TComponent, TProps> =
>LibraryManagedAttributes : LibraryManagedAttributes<TComponent, TProps>
>TComponent : TComponent
>TProps : TProps
TComponent extends { defaultProps: infer D; propTypes: infer P; }
>TComponent : TComponent
>defaultProps : D
>D : D
>propTypes : P
>P : P
? Defaultize<TProps & InferredPropTypes<P>, D>
>Defaultize : Defaultize<TProps, TDefaults>
>TProps : TProps
>InferredPropTypes : InferredPropTypes<P>
>P : P
>D : D
: TComponent extends { defaultProps: infer D }
>TComponent : TComponent
>defaultProps : D
>D : D
? Defaultize<TProps, D>
>Defaultize : Defaultize<TProps, TDefaults>
>TProps : TProps
>D : D
: TComponent extends { propTypes: infer P }
>TComponent : TComponent
>propTypes : P
>P : P
? TProps & InferredPropTypes<P>
>TProps : TProps
>InferredPropTypes : InferredPropTypes<P>
>P : P
: TProps;
>TProps : TProps
}
class Component extends ReactComponent {
>Component : Component
>ReactComponent : ReactComponent<{}, {}>
static propTypes = {
>propTypes : { foo: PropTypeChecker<number, false>; bar: PropTypeChecker<ReactNode, false>; baz: PropTypeChecker<string, true>; }
>{ foo: PropTypes.number, bar: PropTypes.node, baz: PropTypes.string.isRequired, } : { foo: PropTypeChecker<number, false>; bar: PropTypeChecker<ReactNode, false>; baz: PropTypeChecker<string, true>; }
foo: PropTypes.number,
>foo : PropTypeChecker<number, false>
>PropTypes.number : PropTypeChecker<number, false>
>PropTypes : typeof PropTypes
>number : PropTypeChecker<number, false>
bar: PropTypes.node,
>bar : PropTypeChecker<ReactNode, false>
>PropTypes.node : PropTypeChecker<ReactNode, false>
>PropTypes : typeof PropTypes
>node : PropTypeChecker<ReactNode, false>
baz: PropTypes.string.isRequired,
>baz : PropTypeChecker<string, true>
>PropTypes.string.isRequired : PropTypeChecker<string, true>
>PropTypes.string : PropTypeChecker<string, false>
>PropTypes : typeof PropTypes
>string : PropTypeChecker<string, false>
>isRequired : PropTypeChecker<string, true>
};
static defaultProps = {
>defaultProps : { foo: number; }
>{ foo: 42, } : { foo: number; }
foo: 42,
>foo : number
>42 : 42
}
}
const a = <Component foo={12} bar="yes" baz="yeah" />;
>a : JSX.Element
><Component foo={12} bar="yes" baz="yeah" /> : JSX.Element
>Component : typeof Component
>foo : number
>12 : 12
>bar : string
>baz : string
const b = <Component foo={12} />; // Error, missing required prop bar
>b : JSX.Element
><Component foo={12} /> : JSX.Element
>Component : typeof Component
>foo : number
>12 : 12
const c = <Component bar="yes" baz="yeah" />;
>c : JSX.Element
><Component bar="yes" baz="yeah" /> : JSX.Element
>Component : typeof Component
>bar : string
>baz : string
const d = <Component bar="yes" baz="yo" bat="ohno" />; // Error, baz not a valid prop
>d : JSX.Element
><Component bar="yes" baz="yo" bat="ohno" /> : JSX.Element
>Component : typeof Component
>bar : string
>baz : string
>bat : string
const e = <Component foo={12} bar={null} baz="cool" />; // bar is nullable/undefinable since it's not marked `isRequired`
>e : JSX.Element
><Component foo={12} bar={null} baz="cool" /> : JSX.Element
>Component : typeof Component
>foo : number
>12 : 12
>bar : null
>null : null
>baz : string
const f = <Component foo={12} bar="yeah" baz={null} />; // Error, baz is _not_ nullable/undefinable since it's marked `isRequired`
>f : JSX.Element
><Component foo={12} bar="yeah" baz={null} /> : JSX.Element
>Component : typeof Component
>foo : number
>12 : 12
>bar : string
>baz : null
>null : null
class JustPropTypes extends ReactComponent {
>JustPropTypes : JustPropTypes
>ReactComponent : ReactComponent<{}, {}>
static propTypes = {
>propTypes : { foo: PropTypeChecker<number, false>; bar: PropTypeChecker<ReactNode, true>; }
>{ foo: PropTypes.number, bar: PropTypes.node.isRequired, } : { foo: PropTypeChecker<number, false>; bar: PropTypeChecker<ReactNode, true>; }
foo: PropTypes.number,
>foo : PropTypeChecker<number, false>
>PropTypes.number : PropTypeChecker<number, false>
>PropTypes : typeof PropTypes
>number : PropTypeChecker<number, false>
bar: PropTypes.node.isRequired,
>bar : PropTypeChecker<ReactNode, true>
>PropTypes.node.isRequired : PropTypeChecker<ReactNode, true>
>PropTypes.node : PropTypeChecker<ReactNode, false>
>PropTypes : typeof PropTypes
>node : PropTypeChecker<ReactNode, false>
>isRequired : PropTypeChecker<ReactNode, true>
};
}
const g = <JustPropTypes foo={12} bar="ok" />;
>g : JSX.Element
><JustPropTypes foo={12} bar="ok" /> : JSX.Element
>JustPropTypes : typeof JustPropTypes
>foo : number
>12 : 12
>bar : string
const h = <JustPropTypes foo="no" />; // error, wrong type
>h : JSX.Element
><JustPropTypes foo="no" /> : JSX.Element
>JustPropTypes : typeof JustPropTypes
>foo : string
const i = <JustPropTypes foo={null} bar="ok" />;
>i : JSX.Element
><JustPropTypes foo={null} bar="ok" /> : JSX.Element
>JustPropTypes : typeof JustPropTypes
>foo : null
>null : null
>bar : string
const j = <JustPropTypes foo={12} bar={null} />; // error, bar is required
>j : JSX.Element
><JustPropTypes foo={12} bar={null} /> : JSX.Element
>JustPropTypes : typeof JustPropTypes
>foo : number
>12 : 12
>bar : null
>null : null
class JustDefaultProps extends ReactComponent {
>JustDefaultProps : JustDefaultProps
>ReactComponent : ReactComponent<{}, {}>
static defaultProps = {
>defaultProps : { foo: number; }
>{ foo: 42, } : { foo: number; }
foo: 42,
>foo : number
>42 : 42
};
}
const k = <JustDefaultProps foo={12} />;
>k : JSX.Element
><JustDefaultProps foo={12} /> : JSX.Element
>JustDefaultProps : typeof JustDefaultProps
>foo : number
>12 : 12
const l = <JustDefaultProps foo={12} bar="ok" />; // error, no prop named bar
>l : JSX.Element
><JustDefaultProps foo={12} bar="ok" /> : JSX.Element
>JustDefaultProps : typeof JustDefaultProps
>foo : number
>12 : 12
>bar : string
const m = <JustDefaultProps foo="no" />; // error, wrong type
>m : JSX.Element
><JustDefaultProps foo="no" /> : JSX.Element
>JustDefaultProps : typeof JustDefaultProps
>foo : string
interface FooProps {
>FooProps : FooProps
foo: string;
>foo : string
}
class BothWithSpecifiedGeneric extends ReactComponent<FooProps> {
>BothWithSpecifiedGeneric : BothWithSpecifiedGeneric
>ReactComponent : ReactComponent<FooProps, {}>
>FooProps : FooProps
static propTypes = {
>propTypes : { foo: PropTypeChecker<string, false>; bar: PropTypeChecker<ReactNode, false>; baz: PropTypeChecker<number, true>; }
>{ foo: PropTypes.string, bar: PropTypes.node, baz: PropTypes.number.isRequired, } : { foo: PropTypeChecker<string, false>; bar: PropTypeChecker<ReactNode, false>; baz: PropTypeChecker<number, true>; }
foo: PropTypes.string,
>foo : PropTypeChecker<string, false>
>PropTypes.string : PropTypeChecker<string, false>
>PropTypes : typeof PropTypes
>string : PropTypeChecker<string, false>
bar: PropTypes.node,
>bar : PropTypeChecker<ReactNode, false>
>PropTypes.node : PropTypeChecker<ReactNode, false>
>PropTypes : typeof PropTypes
>node : PropTypeChecker<ReactNode, false>
baz: PropTypes.number.isRequired,
>baz : PropTypeChecker<number, true>
>PropTypes.number.isRequired : PropTypeChecker<number, true>
>PropTypes.number : PropTypeChecker<number, false>
>PropTypes : typeof PropTypes
>number : PropTypeChecker<number, false>
>isRequired : PropTypeChecker<number, true>
};
static defaultProps = {
>defaultProps : { foo: string; }
>{ foo: "yo", } : { foo: string; }
foo: "yo",
>foo : string
>"yo" : "yo"
};
}
const n = <BothWithSpecifiedGeneric foo="fine" bar="yes" baz={12} />;
>n : JSX.Element
><BothWithSpecifiedGeneric foo="fine" bar="yes" baz={12} /> : JSX.Element
>BothWithSpecifiedGeneric : typeof BothWithSpecifiedGeneric
>foo : string
>bar : string
>baz : number
>12 : 12
const o = <BothWithSpecifiedGeneric foo="no" />; // Error, missing required prop bar
>o : JSX.Element
><BothWithSpecifiedGeneric foo="no" /> : JSX.Element
>BothWithSpecifiedGeneric : typeof BothWithSpecifiedGeneric
>foo : string
const p = <BothWithSpecifiedGeneric bar="yes" baz={12} />;
>p : JSX.Element
><BothWithSpecifiedGeneric bar="yes" baz={12} /> : JSX.Element
>BothWithSpecifiedGeneric : typeof BothWithSpecifiedGeneric
>bar : string
>baz : number
>12 : 12
const q = <BothWithSpecifiedGeneric bar="yes" baz={12} bat="ohno" />; // Error, baz not a valid prop
>q : JSX.Element
><BothWithSpecifiedGeneric bar="yes" baz={12} bat="ohno" /> : JSX.Element
>BothWithSpecifiedGeneric : typeof BothWithSpecifiedGeneric
>bar : string
>baz : number
>12 : 12
>bat : string
const r = <BothWithSpecifiedGeneric foo="no" bar={null} baz={0} />; // bar is nullable/undefinable since it's not marked `isRequired`
>r : JSX.Element
><BothWithSpecifiedGeneric foo="no" bar={null} baz={0} /> : JSX.Element
>BothWithSpecifiedGeneric : typeof BothWithSpecifiedGeneric
>foo : string
>bar : null
>null : null
>baz : number
>0 : 0
const s = <BothWithSpecifiedGeneric foo="eh" bar="yeah" baz={null} />; // Error, baz is _not_ nullable/undefinable since it's marked `isRequired`
>s : JSX.Element
><BothWithSpecifiedGeneric foo="eh" bar="yeah" baz={null} /> : JSX.Element
>BothWithSpecifiedGeneric : typeof BothWithSpecifiedGeneric
>foo : string
>bar : string
>baz : null
>null : null
class JustPropTypesWithSpecifiedGeneric extends ReactComponent<FooProps> {
>JustPropTypesWithSpecifiedGeneric : JustPropTypesWithSpecifiedGeneric
>ReactComponent : ReactComponent<FooProps, {}>
>FooProps : FooProps
static propTypes = {
>propTypes : { foo: PropTypeChecker<string, false>; bar: PropTypeChecker<ReactNode, true>; }
>{ foo: PropTypes.string, bar: PropTypes.node.isRequired, } : { foo: PropTypeChecker<string, false>; bar: PropTypeChecker<ReactNode, true>; }
foo: PropTypes.string,
>foo : PropTypeChecker<string, false>
>PropTypes.string : PropTypeChecker<string, false>
>PropTypes : typeof PropTypes
>string : PropTypeChecker<string, false>
bar: PropTypes.node.isRequired,
>bar : PropTypeChecker<ReactNode, true>
>PropTypes.node.isRequired : PropTypeChecker<ReactNode, true>
>PropTypes.node : PropTypeChecker<ReactNode, false>
>PropTypes : typeof PropTypes
>node : PropTypeChecker<ReactNode, false>
>isRequired : PropTypeChecker<ReactNode, true>
};
}
const t = <JustPropTypesWithSpecifiedGeneric foo="nice" bar="ok" />;
>t : JSX.Element
><JustPropTypesWithSpecifiedGeneric foo="nice" bar="ok" /> : JSX.Element
>JustPropTypesWithSpecifiedGeneric : typeof JustPropTypesWithSpecifiedGeneric
>foo : string
>bar : string
const u = <JustPropTypesWithSpecifiedGeneric foo={12} />; // error, wrong type
>u : JSX.Element
><JustPropTypesWithSpecifiedGeneric foo={12} /> : JSX.Element
>JustPropTypesWithSpecifiedGeneric : typeof JustPropTypesWithSpecifiedGeneric
>foo : number
>12 : 12
const v = <JustPropTypesWithSpecifiedGeneric foo={null} bar="ok" />; // generic overrides propTypes required-ness, null isn't valid
>v : JSX.Element
><JustPropTypesWithSpecifiedGeneric foo={null} bar="ok" /> : JSX.Element
>JustPropTypesWithSpecifiedGeneric : typeof JustPropTypesWithSpecifiedGeneric
>foo : null
>null : null
>bar : string
const w = <JustPropTypesWithSpecifiedGeneric foo="cool" bar={null} />; // error, bar is required
>w : JSX.Element
><JustPropTypesWithSpecifiedGeneric foo="cool" bar={null} /> : JSX.Element
>JustPropTypesWithSpecifiedGeneric : typeof JustPropTypesWithSpecifiedGeneric
>foo : string
>bar : null
>null : null
class JustDefaultPropsWithSpecifiedGeneric extends ReactComponent<FooProps> {
>JustDefaultPropsWithSpecifiedGeneric : JustDefaultPropsWithSpecifiedGeneric
>ReactComponent : ReactComponent<FooProps, {}>
>FooProps : FooProps
static defaultProps = {
>defaultProps : { foo: string; }
>{ foo: "no", } : { foo: string; }
foo: "no",
>foo : string
>"no" : "no"
};
}
const x = <JustDefaultPropsWithSpecifiedGeneric foo="eh" />;
>x : JSX.Element
><JustDefaultPropsWithSpecifiedGeneric foo="eh" /> : JSX.Element
>JustDefaultPropsWithSpecifiedGeneric : typeof JustDefaultPropsWithSpecifiedGeneric
>foo : string
const y = <JustDefaultPropsWithSpecifiedGeneric foo="no" bar="ok" />; // error, no prop named bar
>y : JSX.Element
><JustDefaultPropsWithSpecifiedGeneric foo="no" bar="ok" /> : JSX.Element
>JustDefaultPropsWithSpecifiedGeneric : typeof JustDefaultPropsWithSpecifiedGeneric
>foo : string
>bar : string
const z = <JustDefaultPropsWithSpecifiedGeneric foo={12} />; // error, wrong type
>z : JSX.Element
><JustDefaultPropsWithSpecifiedGeneric foo={12} /> : JSX.Element
>JustDefaultPropsWithSpecifiedGeneric : typeof JustDefaultPropsWithSpecifiedGeneric
>foo : number
>12 : 12
const aa = <JustDefaultPropsWithSpecifiedGeneric />;
>aa : JSX.Element
><JustDefaultPropsWithSpecifiedGeneric /> : JSX.Element
>JustDefaultPropsWithSpecifiedGeneric : typeof JustDefaultPropsWithSpecifiedGeneric
@@ -0,0 +1,127 @@
// @jsx: preserve
// @strict: true
type Defaultize<TProps, TDefaults> =
& {[K in Extract<keyof TProps, keyof TDefaults>]?: TProps[K]}
& {[K in Exclude<keyof TProps, keyof TDefaults>]: TProps[K]}
& Partial<TDefaults>;
type InferredPropTypes<P> = {[K in keyof P]: P[K] extends PropTypeChecker<infer T, infer U> ? PropTypeChecker<T, U>[typeof checkedType] : {}};
declare const checkedType: unique symbol;
interface PropTypeChecker<U, TRequired = false> {
(props: any, propName: string, componentName: string, location: any, propFullName: string): boolean;
isRequired: PropTypeChecker<U, true>;
[checkedType]: TRequired extends true ? U : U | null | undefined;
}
declare namespace PropTypes {
export const number: PropTypeChecker<number>;
export const string: PropTypeChecker<string>;
export const node: PropTypeChecker<ReactNode>;
}
type ReactNode = string | number | ReactComponent<{}, {}>;
declare class ReactComponent<P={}, S={}> {
constructor(props: P);
props: P & Readonly<{children: ReactNode[]}>;
setState(s: Partial<S>): S;
render(): ReactNode;
}
declare namespace JSX {
interface Element extends ReactComponent {}
interface IntrinsicElements {}
type LibraryManagedAttributes<TComponent, TProps> =
TComponent extends { defaultProps: infer D; propTypes: infer P; }
? Defaultize<TProps & InferredPropTypes<P>, D>
: TComponent extends { defaultProps: infer D }
? Defaultize<TProps, D>
: TComponent extends { propTypes: infer P }
? TProps & InferredPropTypes<P>
: TProps;
}
class Component extends ReactComponent {
static propTypes = {
foo: PropTypes.number,
bar: PropTypes.node,
baz: PropTypes.string.isRequired,
};
static defaultProps = {
foo: 42,
}
}
const a = <Component foo={12} bar="yes" baz="yeah" />;
const b = <Component foo={12} />; // Error, missing required prop bar
const c = <Component bar="yes" baz="yeah" />;
const d = <Component bar="yes" baz="yo" bat="ohno" />; // Error, baz not a valid prop
const e = <Component foo={12} bar={null} baz="cool" />; // bar is nullable/undefinable since it's not marked `isRequired`
const f = <Component foo={12} bar="yeah" baz={null} />; // Error, baz is _not_ nullable/undefinable since it's marked `isRequired`
class JustPropTypes extends ReactComponent {
static propTypes = {
foo: PropTypes.number,
bar: PropTypes.node.isRequired,
};
}
const g = <JustPropTypes foo={12} bar="ok" />;
const h = <JustPropTypes foo="no" />; // error, wrong type
const i = <JustPropTypes foo={null} bar="ok" />;
const j = <JustPropTypes foo={12} bar={null} />; // error, bar is required
class JustDefaultProps extends ReactComponent {
static defaultProps = {
foo: 42,
};
}
const k = <JustDefaultProps foo={12} />;
const l = <JustDefaultProps foo={12} bar="ok" />; // error, no prop named bar
const m = <JustDefaultProps foo="no" />; // error, wrong type
interface FooProps {
foo: string;
}
class BothWithSpecifiedGeneric extends ReactComponent<FooProps> {
static propTypes = {
foo: PropTypes.string,
bar: PropTypes.node,
baz: PropTypes.number.isRequired,
};
static defaultProps = {
foo: "yo",
};
}
const n = <BothWithSpecifiedGeneric foo="fine" bar="yes" baz={12} />;
const o = <BothWithSpecifiedGeneric foo="no" />; // Error, missing required prop bar
const p = <BothWithSpecifiedGeneric bar="yes" baz={12} />;
const q = <BothWithSpecifiedGeneric bar="yes" baz={12} bat="ohno" />; // Error, baz not a valid prop
const r = <BothWithSpecifiedGeneric foo="no" bar={null} baz={0} />; // bar is nullable/undefinable since it's not marked `isRequired`
const s = <BothWithSpecifiedGeneric foo="eh" bar="yeah" baz={null} />; // Error, baz is _not_ nullable/undefinable since it's marked `isRequired`
class JustPropTypesWithSpecifiedGeneric extends ReactComponent<FooProps> {
static propTypes = {
foo: PropTypes.string,
bar: PropTypes.node.isRequired,
};
}
const t = <JustPropTypesWithSpecifiedGeneric foo="nice" bar="ok" />;
const u = <JustPropTypesWithSpecifiedGeneric foo={12} />; // error, wrong type
const v = <JustPropTypesWithSpecifiedGeneric foo={null} bar="ok" />; // generic overrides propTypes required-ness, null isn't valid
const w = <JustPropTypesWithSpecifiedGeneric foo="cool" bar={null} />; // error, bar is required
class JustDefaultPropsWithSpecifiedGeneric extends ReactComponent<FooProps> {
static defaultProps = {
foo: "no",
};
}
const x = <JustDefaultPropsWithSpecifiedGeneric foo="eh" />;
const y = <JustDefaultPropsWithSpecifiedGeneric foo="no" bar="ok" />; // error, no prop named bar
const z = <JustDefaultPropsWithSpecifiedGeneric foo={12} />; // error, wrong type
const aa = <JustDefaultPropsWithSpecifiedGeneric />;