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

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
}
}