mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
Apply formatting fixes
This commit is contained in:
parent
5d94666678
commit
7f0a0e542b
@ -29380,59 +29380,59 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getDiscriminantPropertyAccess(expr: Expression, computedType: Type) {
|
||||
// As long as the computed type is a subset of the declared type, we use the full declared type to detect
|
||||
// a discriminant property. In cases where the computed type isn't a subset, e.g because of a preceding type
|
||||
// predicate narrowing, we use the actual computed type.
|
||||
if (declaredType.flags & TypeFlags.Union || computedType.flags & TypeFlags.Union) {
|
||||
const access = getCandidateDiscriminantPropertyAccess(expr);
|
||||
if (access) {
|
||||
const name = getAccessedPropertyName(access);
|
||||
if (name) {
|
||||
const type = declaredType.flags & TypeFlags.Union && isTypeSubsetOf(computedType, declaredType) ? declaredType : computedType;
|
||||
if (isDiscriminantProperty(type, name)) {
|
||||
return access;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fix for #23572: Allow discriminant property narrowing for non-union types
|
||||
// This enables narrowing to never when all possibilities are eliminated
|
||||
else {
|
||||
const access = getCandidateDiscriminantPropertyAccess(expr);
|
||||
if (access) {
|
||||
const name = getAccessedPropertyName(access);
|
||||
if (name) {
|
||||
// For non-union types, check if the property exists and has a literal type
|
||||
const type = declaredType.flags & TypeFlags.Union && isTypeSubsetOf(computedType, declaredType) ? declaredType : computedType;
|
||||
const propType = getTypeOfPropertyOfType(type, name);
|
||||
if (propType && isUnitLikeType(propType)) {
|
||||
return access;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
function getDiscriminantPropertyAccess(expr: Expression, computedType: Type) {
|
||||
// As long as the computed type is a subset of the declared type, we use the full declared type to detect
|
||||
// a discriminant property. In cases where the computed type isn't a subset, e.g because of a preceding type
|
||||
// predicate narrowing, we use the actual computed type.
|
||||
if (declaredType.flags & TypeFlags.Union || computedType.flags & TypeFlags.Union) {
|
||||
const access = getCandidateDiscriminantPropertyAccess(expr);
|
||||
if (access) {
|
||||
const name = getAccessedPropertyName(access);
|
||||
if (name) {
|
||||
const type = declaredType.flags & TypeFlags.Union && isTypeSubsetOf(computedType, declaredType) ? declaredType : computedType;
|
||||
if (isDiscriminantProperty(type, name)) {
|
||||
return access;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fix for #23572: Allow discriminant property narrowing for non-union types
|
||||
// This enables narrowing to never when all possibilities are eliminated
|
||||
else {
|
||||
const access = getCandidateDiscriminantPropertyAccess(expr);
|
||||
if (access) {
|
||||
const name = getAccessedPropertyName(access);
|
||||
if (name) {
|
||||
// For non-union types, check if the property exists and has a literal type
|
||||
const type = declaredType.flags & TypeFlags.Union && isTypeSubsetOf(computedType, declaredType) ? declaredType : computedType;
|
||||
const propType = getTypeOfPropertyOfType(type, name);
|
||||
if (propType && isUnitLikeType(propType)) {
|
||||
return access;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function narrowTypeByDiscriminant(type: Type, access: AccessExpression | BindingElement | ParameterDeclaration, narrowType: (t: Type) => Type): Type {
|
||||
const propName = getAccessedPropertyName(access);
|
||||
if (propName === undefined) {
|
||||
return type;
|
||||
}
|
||||
const optionalChain = isOptionalChain(access);
|
||||
const removeNullable = strictNullChecks && (optionalChain || isNonNullAccess(access)) && maybeTypeOfKind(type, TypeFlags.Nullable);
|
||||
let propType = getTypeOfPropertyOfType(removeNullable ? getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type, propName);
|
||||
if (!propType) {
|
||||
return type;
|
||||
}
|
||||
propType = removeNullable && optionalChain ? getOptionalType(propType) : propType;
|
||||
const narrowedPropType = narrowType(propType);
|
||||
return filterType(type, t => {
|
||||
const discriminantType = getTypeOfPropertyOrIndexSignatureOfType(t, propName) || unknownType;
|
||||
const result = !(discriminantType.flags & TypeFlags.Never) && !(narrowedPropType.flags & TypeFlags.Never) && areTypesComparable(narrowedPropType, discriminantType);
|
||||
return result;
|
||||
});
|
||||
function narrowTypeByDiscriminant(type: Type, access: AccessExpression | BindingElement | ParameterDeclaration, narrowType: (t: Type) => Type): Type {
|
||||
const propName = getAccessedPropertyName(access);
|
||||
if (propName === undefined) {
|
||||
return type;
|
||||
}
|
||||
const optionalChain = isOptionalChain(access);
|
||||
const removeNullable = strictNullChecks && (optionalChain || isNonNullAccess(access)) && maybeTypeOfKind(type, TypeFlags.Nullable);
|
||||
let propType = getTypeOfPropertyOfType(removeNullable ? getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type, propName);
|
||||
if (!propType) {
|
||||
return type;
|
||||
}
|
||||
propType = removeNullable && optionalChain ? getOptionalType(propType) : propType;
|
||||
const narrowedPropType = narrowType(propType);
|
||||
return filterType(type, t => {
|
||||
const discriminantType = getTypeOfPropertyOrIndexSignatureOfType(t, propName) || unknownType;
|
||||
const result = !(discriminantType.flags & TypeFlags.Never) && !(narrowedPropType.flags & TypeFlags.Never) && areTypesComparable(narrowedPropType, discriminantType);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
function narrowTypeByDiscriminantProperty(type: Type, access: AccessExpression | BindingElement | ParameterDeclaration, operator: SyntaxKind, value: Expression, assumeTrue: boolean) {
|
||||
@ -29635,43 +29635,43 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return removeNullable ? getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type;
|
||||
}
|
||||
|
||||
function narrowTypeByEquality(type: Type, operator: SyntaxKind, value: Expression, assumeTrue: boolean): Type {
|
||||
if (type.flags & TypeFlags.Any) {
|
||||
return type;
|
||||
}
|
||||
if (operator === SyntaxKind.ExclamationEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) {
|
||||
assumeTrue = !assumeTrue;
|
||||
}
|
||||
const valueType = getTypeOfExpression(value);
|
||||
const doubleEquals = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsToken;
|
||||
if (valueType.flags & TypeFlags.Nullable) {
|
||||
if (!strictNullChecks) {
|
||||
return type;
|
||||
}
|
||||
const facts = doubleEquals ?
|
||||
assumeTrue ? TypeFacts.EQUndefinedOrNull : TypeFacts.NEUndefinedOrNull :
|
||||
valueType.flags & TypeFlags.Null ?
|
||||
assumeTrue ? TypeFacts.EQNull : TypeFacts.NENull :
|
||||
assumeTrue ? TypeFacts.EQUndefined : TypeFacts.NEUndefined;
|
||||
return getAdjustedTypeWithFacts(type, facts);
|
||||
}
|
||||
if (assumeTrue) {
|
||||
if (!doubleEquals && (type.flags & TypeFlags.Unknown || someType(type, isEmptyAnonymousObjectType))) {
|
||||
if (valueType.flags & (TypeFlags.Primitive | TypeFlags.NonPrimitive) || isEmptyAnonymousObjectType(valueType)) {
|
||||
return valueType;
|
||||
}
|
||||
if (valueType.flags & TypeFlags.Object) {
|
||||
return nonPrimitiveType;
|
||||
}
|
||||
}
|
||||
const filteredType = filterType(type, t => areTypesComparable(t, valueType) || doubleEquals && isCoercibleUnderDoubleEquals(t, valueType));
|
||||
return replacePrimitivesWithLiterals(filteredType, valueType);
|
||||
}
|
||||
if (isUnitType(valueType)) {
|
||||
const result = filterType(type, t => !(isUnitLikeType(t) && areTypesComparable(t, valueType)));
|
||||
return result;
|
||||
}
|
||||
return type;
|
||||
function narrowTypeByEquality(type: Type, operator: SyntaxKind, value: Expression, assumeTrue: boolean): Type {
|
||||
if (type.flags & TypeFlags.Any) {
|
||||
return type;
|
||||
}
|
||||
if (operator === SyntaxKind.ExclamationEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) {
|
||||
assumeTrue = !assumeTrue;
|
||||
}
|
||||
const valueType = getTypeOfExpression(value);
|
||||
const doubleEquals = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsToken;
|
||||
if (valueType.flags & TypeFlags.Nullable) {
|
||||
if (!strictNullChecks) {
|
||||
return type;
|
||||
}
|
||||
const facts = doubleEquals ?
|
||||
assumeTrue ? TypeFacts.EQUndefinedOrNull : TypeFacts.NEUndefinedOrNull :
|
||||
valueType.flags & TypeFlags.Null ?
|
||||
assumeTrue ? TypeFacts.EQNull : TypeFacts.NENull :
|
||||
assumeTrue ? TypeFacts.EQUndefined : TypeFacts.NEUndefined;
|
||||
return getAdjustedTypeWithFacts(type, facts);
|
||||
}
|
||||
if (assumeTrue) {
|
||||
if (!doubleEquals && (type.flags & TypeFlags.Unknown || someType(type, isEmptyAnonymousObjectType))) {
|
||||
if (valueType.flags & (TypeFlags.Primitive | TypeFlags.NonPrimitive) || isEmptyAnonymousObjectType(valueType)) {
|
||||
return valueType;
|
||||
}
|
||||
if (valueType.flags & TypeFlags.Object) {
|
||||
return nonPrimitiveType;
|
||||
}
|
||||
}
|
||||
const filteredType = filterType(type, t => areTypesComparable(t, valueType) || doubleEquals && isCoercibleUnderDoubleEquals(t, valueType));
|
||||
return replacePrimitivesWithLiterals(filteredType, valueType);
|
||||
}
|
||||
if (isUnitType(valueType)) {
|
||||
const result = filterType(type, t => !(isUnitLikeType(t) && areTypesComparable(t, valueType)));
|
||||
return result;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function narrowTypeByTypeof(type: Type, typeOfExpr: TypeOfExpression, operator: SyntaxKind, literal: LiteralExpression, assumeTrue: boolean): Type {
|
||||
@ -39268,33 +39268,33 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return links.isExhaustive;
|
||||
}
|
||||
|
||||
function computeExhaustiveSwitchStatement(node: SwitchStatement): boolean {
|
||||
if (node.expression.kind === SyntaxKind.TypeOfExpression) {
|
||||
const witnesses = getSwitchClauseTypeOfWitnesses(node);
|
||||
if (!witnesses) {
|
||||
return false;
|
||||
}
|
||||
const operandConstraint = getBaseConstraintOrType(checkExpressionCached((node.expression as TypeOfExpression).expression));
|
||||
// Get the not-equal flags for all handled cases.
|
||||
const notEqualFacts = getNotEqualFactsFromTypeofSwitch(0, 0, witnesses);
|
||||
if (operandConstraint.flags & TypeFlags.AnyOrUnknown) {
|
||||
// We special case the top types to be exhaustive when all cases are handled.
|
||||
return (TypeFacts.AllTypeofNE & notEqualFacts) === TypeFacts.AllTypeofNE;
|
||||
}
|
||||
// A missing not-equal flag indicates that the type wasn't handled by some case.
|
||||
return !someType(operandConstraint, t => getTypeFacts(t, notEqualFacts) === notEqualFacts);
|
||||
}
|
||||
const type = getBaseConstraintOrType(checkExpressionCached(node.expression));
|
||||
if (!isLiteralType(type)) {
|
||||
return false;
|
||||
}
|
||||
const switchTypes = getSwitchClauseTypes(node);
|
||||
if (!switchTypes.length || some(switchTypes, isNeitherUnitTypeNorNever)) {
|
||||
return false;
|
||||
}
|
||||
const mappedType = mapType(type, getRegularTypeOfLiteralType);
|
||||
const result = eachTypeContainedIn(mappedType, switchTypes);
|
||||
return result;
|
||||
function computeExhaustiveSwitchStatement(node: SwitchStatement): boolean {
|
||||
if (node.expression.kind === SyntaxKind.TypeOfExpression) {
|
||||
const witnesses = getSwitchClauseTypeOfWitnesses(node);
|
||||
if (!witnesses) {
|
||||
return false;
|
||||
}
|
||||
const operandConstraint = getBaseConstraintOrType(checkExpressionCached((node.expression as TypeOfExpression).expression));
|
||||
// Get the not-equal flags for all handled cases.
|
||||
const notEqualFacts = getNotEqualFactsFromTypeofSwitch(0, 0, witnesses);
|
||||
if (operandConstraint.flags & TypeFlags.AnyOrUnknown) {
|
||||
// We special case the top types to be exhaustive when all cases are handled.
|
||||
return (TypeFacts.AllTypeofNE & notEqualFacts) === TypeFacts.AllTypeofNE;
|
||||
}
|
||||
// A missing not-equal flag indicates that the type wasn't handled by some case.
|
||||
return !someType(operandConstraint, t => getTypeFacts(t, notEqualFacts) === notEqualFacts);
|
||||
}
|
||||
const type = getBaseConstraintOrType(checkExpressionCached(node.expression));
|
||||
if (!isLiteralType(type)) {
|
||||
return false;
|
||||
}
|
||||
const switchTypes = getSwitchClauseTypes(node);
|
||||
if (!switchTypes.length || some(switchTypes, isNeitherUnitTypeNorNever)) {
|
||||
return false;
|
||||
}
|
||||
const mappedType = mapType(type, getRegularTypeOfLiteralType);
|
||||
const result = eachTypeContainedIn(mappedType, switchTypes);
|
||||
return result;
|
||||
}
|
||||
|
||||
function functionHasImplicitReturn(func: FunctionLikeDeclaration) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user