@@ -3286,6 +3286,16 @@ namespace ts {
3286
3286
return strictNullChecks && optional ? includeFalsyTypes(type, TypeFlags.Undefined) : type;
3287
3287
}
3288
3288
3289
+ /** remove undefined from the annotated type of a parameter when there is an initializer (that doesn't include undefined) */
3290
+ function removeOptionalityFromAnnotation(annotatedType: Type, declaration: VariableLikeDeclaration): Type {
3291
+ const annotationIncludesUndefined = strictNullChecks &&
3292
+ declaration.kind === SyntaxKind.Parameter &&
3293
+ declaration.initializer &&
3294
+ getFalsyFlags(annotatedType) & TypeFlags.Undefined &&
3295
+ !(getFalsyFlags(checkExpression(declaration.initializer)) & TypeFlags.Undefined);
3296
+ return annotationIncludesUndefined ? getNonNullableType(annotatedType) : annotatedType;
3297
+ }
3298
+
3289
3299
// Return the inferred type for a variable, parameter, or property declaration
3290
3300
function getTypeForVariableLikeDeclaration(declaration: VariableLikeDeclaration, includeOptionality: boolean): Type {
3291
3301
if (declaration.flags & NodeFlags.JavaScriptFile) {
@@ -3319,7 +3329,8 @@ namespace ts {
3319
3329
3320
3330
// Use type from type annotation if one is present
3321
3331
if (declaration.type) {
3322
- return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ declaration.questionToken && includeOptionality);
3332
+ const declaredType = removeOptionalityFromAnnotation(getTypeFromTypeNode(declaration.type), declaration);
3333
+ return addOptionality(declaredType, /*optional*/ declaration.questionToken && includeOptionality);
3323
3334
}
3324
3335
3325
3336
if ((compilerOptions.noImplicitAny || declaration.flags & NodeFlags.JavaScriptFile) &&
0 commit comments