Skip to content

Commit

Permalink
Change the default type parameter constraint and default to unknown f…
Browse files Browse the repository at this point in the history
…rom {}
  • Loading branch information
weswigham committed Mar 28, 2019
1 parent b7881a2 commit a560fd6
Show file tree
Hide file tree
Showing 128 changed files with 1,238 additions and 849 deletions.
40 changes: 20 additions & 20 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7325,7 +7325,7 @@ namespace ts {
const declaredType = <MappedType>getTypeFromMappedTypeNode(type.declaration);
const constraint = getConstraintTypeFromMappedType(declaredType);
const extendedConstraint = constraint && constraint.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(<TypeParameter>constraint) : constraint;
type.modifiersType = extendedConstraint && extendedConstraint.flags & TypeFlags.Index ? instantiateType((<IndexType>extendedConstraint).type, type.mapper || identityMapper) : emptyObjectType;
type.modifiersType = extendedConstraint && extendedConstraint.flags & TypeFlags.Index ? instantiateType((<IndexType>extendedConstraint).type, type.mapper || identityMapper) : unknownType;
}
}
return type.modifiersType;
Expand Down Expand Up @@ -7768,7 +7768,7 @@ namespace ts {
* type itself. Note that the apparent type of a union type is the union type itself.
*/
function getApparentType(type: Type): Type {
const t = type.flags & TypeFlags.Instantiable ? getBaseConstraintOfType(type) || emptyObjectType : type;
const t = type.flags & TypeFlags.Instantiable ? getBaseConstraintOfType(type) || (strictNullChecks ? unknownType : emptyObjectType) : type;
return getObjectFlags(t) & ObjectFlags.Mapped ? getApparentTypeOfMappedType(<MappedType>t) :
t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(<IntersectionType>t) :
t.flags & TypeFlags.StringLike ? globalStringType :
Expand Down Expand Up @@ -8101,7 +8101,7 @@ namespace ts {
const baseDefaultType = getDefaultTypeArgumentType(isJavaScriptImplicitAny);
for (let i = numTypeArguments; i < numTypeParameters; i++) {
let defaultType = getDefaultFromTypeParameter(typeParameters![i]);
if (isJavaScriptImplicitAny && defaultType && isTypeIdenticalTo(defaultType, emptyObjectType)) {
if (isJavaScriptImplicitAny && defaultType && (isTypeIdenticalTo(defaultType, unknownType) || isTypeIdenticalTo(defaultType, emptyObjectType))) {
defaultType = anyType;
}
result[i] = defaultType ? instantiateType(defaultType, createTypeMapper(typeParameters!, result)) : baseDefaultType;
Expand Down Expand Up @@ -8480,7 +8480,7 @@ namespace ts {
const typeParameters = signature.typeParameters;
if (typeParameters) {
const typeEraser = createTypeEraser(typeParameters);
const baseConstraints = map(typeParameters, tp => instantiateType(getBaseConstraintOfType(tp), typeEraser) || emptyObjectType);
const baseConstraints = map(typeParameters, tp => instantiateType(getBaseConstraintOfType(tp), typeEraser) || unknownType);
return instantiateSignature(signature, createTypeMapper(typeParameters, baseConstraints), /*eraseTypeParameters*/ true);
}
return signature;
Expand Down Expand Up @@ -10794,7 +10794,7 @@ namespace ts {
* This is used during inference when instantiating type parameter defaults.
*/
function createBackreferenceMapper(context: InferenceContext, index: number): TypeMapper {
return t => findIndex(context.inferences, info => info.typeParameter === t) >= index ? emptyObjectType : t;
return t => findIndex(context.inferences, info => info.typeParameter === t) >= index ? unknownType : t;
}

function combineTypeMappers(mapper1: TypeMapper | undefined, mapper2: TypeMapper): TypeMapper;
Expand Down Expand Up @@ -11341,7 +11341,7 @@ namespace ts {
function isTypeDerivedFrom(source: Type, target: Type): boolean {
return source.flags & TypeFlags.Union ? every((<UnionType>source).types, t => isTypeDerivedFrom(t, target)) :
target.flags & TypeFlags.Union ? some((<UnionType>target).types, t => isTypeDerivedFrom(source, t)) :
source.flags & TypeFlags.InstantiableNonPrimitive ? isTypeDerivedFrom(getBaseConstraintOfType(source) || emptyObjectType, target) :
source.flags & TypeFlags.InstantiableNonPrimitive ? isTypeDerivedFrom(getBaseConstraintOfType(source) || unknownType, target) :
target === globalObjectType ? !!(source.flags & (TypeFlags.Object | TypeFlags.NonPrimitive)) :
target === globalFunctionType ? !!(source.flags & TypeFlags.Object) && isFunctionObjectType(source as ObjectType) :
hasBaseType(source, getTargetType(target));
Expand Down Expand Up @@ -14539,7 +14539,7 @@ namespace ts {
function getTypeFromInference(inference: InferenceInfo) {
return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) :
inference.contraCandidates ? getIntersectionType(inference.contraCandidates) :
emptyObjectType;
unknownType;
}

function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0, contravariant = false) {
Expand Down Expand Up @@ -15097,7 +15097,7 @@ namespace ts {
}

function getDefaultTypeArgumentType(isInJavaScriptFile: boolean): Type {
return isInJavaScriptFile ? anyType : emptyObjectType;
return isInJavaScriptFile ? anyType : unknownType;
}

function getInferredTypes(context: InferenceContext): Type[] {
Expand Down Expand Up @@ -15441,7 +15441,7 @@ namespace ts {
return strictNullChecks ? TypeFacts.ObjectStrictFacts : TypeFacts.ObjectFacts;
}
if (flags & TypeFlags.Instantiable) {
return getTypeFacts(getBaseConstraintOfType(type) || emptyObjectType);
return getTypeFacts(getBaseConstraintOfType(type) || unknownType);
}
if (flags & TypeFlags.UnionOrIntersection) {
return getTypeFactsOfTypes((<UnionOrIntersectionType>type).types);
Expand Down Expand Up @@ -16752,7 +16752,7 @@ namespace ts {
}

function typeHasNullableConstraint(type: Type) {
return type.flags & TypeFlags.InstantiableNonPrimitive && maybeTypeOfKind(getBaseConstraintOfType(type) || emptyObjectType, TypeFlags.Nullable);
return type.flags & TypeFlags.InstantiableNonPrimitive && maybeTypeOfKind(getBaseConstraintOfType(type) || unknownType, TypeFlags.Nullable);
}

function getConstraintForLocation(type: Type, node: Node): Type;
Expand Down Expand Up @@ -18194,7 +18194,7 @@ namespace ts {
}

function getJsxPropsTypeFromCallSignature(sig: Signature, context: JsxOpeningLikeElement) {
let propsType = getTypeOfFirstParameterOfSignatureWithFallback(sig, emptyObjectType);
let propsType = getTypeOfFirstParameterOfSignatureWithFallback(sig, unknownType);
propsType = getJsxManagedAttributesFromLocatedAttributes(context, getJsxNamespaceAt(context), propsType);
const intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context);
if (intrinsicAttribs !== errorType) {
Expand Down Expand Up @@ -18268,7 +18268,7 @@ namespace ts {
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)
? getTypeOfFirstParameterOfSignatureWithFallback(sig, unknownType)
: forcedLookupLocation === ""
// If there is no e.g. 'props' member in ElementAttributesProperty, use the element class type instead
? getReturnTypeOfSignature(sig)
Expand All @@ -18280,7 +18280,7 @@ namespace ts {
if (!!forcedLookupLocation && !!length(context.attributes.properties)) {
error(context, Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, unescapeLeadingUnderscores(forcedLookupLocation));
}
return emptyObjectType;
return unknownType;
}

attributesType = getJsxManagedAttributesFromLocatedAttributes(context, ns, attributesType);
Expand Down Expand Up @@ -21986,7 +21986,7 @@ namespace ts {
const decl = parameter.valueDeclaration as ParameterDeclaration;
if (decl.name.kind !== SyntaxKind.Identifier) {
// if inference didn't come up with anything but {}, fall back to the binding pattern if present.
if (links.type === emptyObjectType) {
if (links.type === unknownType) {
links.type = getTypeFromBindingPattern(decl.name);
}
assignBindingElementTypes(decl.name);
Expand All @@ -21999,28 +21999,28 @@ namespace ts {
const globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true);
if (globalPromiseType !== emptyGenericType) {
// if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type
promisedType = getAwaitedType(promisedType) || emptyObjectType;
promisedType = getAwaitedType(promisedType) || unknownType;
return createTypeReference(globalPromiseType, [promisedType]);
}

return emptyObjectType;
return unknownType;
}

function createPromiseLikeType(promisedType: Type): Type {
// creates a `PromiseLike<T>` type where `T` is the promisedType argument
const globalPromiseLikeType = getGlobalPromiseLikeType(/*reportErrors*/ true);
if (globalPromiseLikeType !== emptyGenericType) {
// if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type
promisedType = getAwaitedType(promisedType) || emptyObjectType;
promisedType = getAwaitedType(promisedType) || unknownType;
return createTypeReference(globalPromiseLikeType, [promisedType]);
}

return emptyObjectType;
return unknownType;
}

function createPromiseReturnType(func: FunctionLikeDeclaration | ImportCall, promisedType: Type) {
const promiseType = createPromiseType(promisedType);
if (promiseType === emptyObjectType) {
if (promiseType === unknownType) {
error(func, isImportCall(func) ?
Diagnostics.A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option :
Diagnostics.An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option);
Expand Down Expand Up @@ -23453,7 +23453,7 @@ namespace ts {
// If the contextual type is a type variable constrained to a primitive type, consider
// this a literal context for literals of that primitive type. For example, given a
// type parameter 'T extends string', infer string literal types for T.
const constraint = getBaseConstraintOfType(contextualType) || emptyObjectType;
const constraint = getBaseConstraintOfType(contextualType) || unknownType;
return maybeTypeOfKind(constraint, TypeFlags.String) && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral) ||
maybeTypeOfKind(constraint, TypeFlags.Number) && maybeTypeOfKind(candidateType, TypeFlags.NumberLiteral) ||
maybeTypeOfKind(constraint, TypeFlags.BigInt) && maybeTypeOfKind(candidateType, TypeFlags.BigIntLiteral) ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,24 +136,24 @@ class C2<T, U> {
}
}
var r6 = (new C2()).f<number>(1, '');
>r6 : {}
>(new C2()).f<number>(1, '') : {}
>(new C2()).f : (x: {}, y: {}) => {}
>(new C2()) : C2<{}, {}>
>new C2() : C2<{}, {}>
>r6 : unknown
>(new C2()).f<number>(1, '') : unknown
>(new C2()).f : (x: unknown, y: unknown) => unknown
>(new C2()) : C2<unknown, unknown>
>new C2() : C2<unknown, unknown>
>C2 : typeof C2
>f : (x: {}, y: {}) => {}
>f : (x: unknown, y: unknown) => unknown
>1 : 1
>'' : ""

var r6b = (new C2()).f<number, string, number>(1, '');
>r6b : {}
>(new C2()).f<number, string, number>(1, '') : {}
>(new C2()).f : (x: {}, y: {}) => {}
>(new C2()) : C2<{}, {}>
>new C2() : C2<{}, {}>
>r6b : unknown
>(new C2()).f<number, string, number>(1, '') : unknown
>(new C2()).f : (x: unknown, y: unknown) => unknown
>(new C2()) : C2<unknown, unknown>
>new C2() : C2<unknown, unknown>
>C2 : typeof C2
>f : (x: {}, y: {}) => {}
>f : (x: unknown, y: unknown) => unknown
>1 : 1
>'' : ""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,13 @@ class C2<T> {
}
}
var r6 = (new C2()).f(1);
>r6 : {}
>(new C2()).f(1) : {}
>(new C2()).f : (x: {}) => {}
>(new C2()) : C2<{}>
>new C2() : C2<{}>
>r6 : unknown
>(new C2()).f(1) : unknown
>(new C2()).f : (x: unknown) => unknown
>(new C2()) : C2<unknown>
>new C2() : C2<unknown>
>C2 : typeof C2
>f : (x: {}) => {}
>f : (x: unknown) => unknown
>1 : 1

interface I2<T> {
Expand Down
Loading

0 comments on commit a560fd6

Please sign in to comment.