Merge pull request #12033 from Microsoft/add-undefined-to-default-valued-parameters
Add undefined to default-initialised parameters
This commit is contained in:
commit
46d9f37020
9 changed files with 534 additions and 11 deletions
|
@ -2690,7 +2690,11 @@ namespace ts {
|
|||
writePunctuation(writer, SyntaxKind.ColonToken);
|
||||
writeSpace(writer);
|
||||
|
||||
buildTypeDisplay(getTypeOfSymbol(p), writer, enclosingDeclaration, flags, symbolStack);
|
||||
let type = getTypeOfSymbol(p);
|
||||
if (isRequiredInitializedParameter(parameterNode)) {
|
||||
type = includeFalsyTypes(type, TypeFlags.Undefined);
|
||||
}
|
||||
buildTypeDisplay(type, writer, enclosingDeclaration, flags, symbolStack);
|
||||
}
|
||||
|
||||
function buildBindingPatternDisplay(bindingPattern: BindingPattern, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) {
|
||||
|
@ -3271,6 +3275,16 @@ namespace ts {
|
|||
return strictNullChecks && optional ? includeFalsyTypes(type, TypeFlags.Undefined) : type;
|
||||
}
|
||||
|
||||
/** remove undefined from the annotated type of a parameter when there is an initializer (that doesn't include undefined) */
|
||||
function removeOptionalityFromAnnotation(annotatedType: Type, declaration: VariableLikeDeclaration): Type {
|
||||
const annotationIncludesUndefined = strictNullChecks &&
|
||||
declaration.kind === SyntaxKind.Parameter &&
|
||||
declaration.initializer &&
|
||||
getFalsyFlags(annotatedType) & TypeFlags.Undefined &&
|
||||
!(getFalsyFlags(checkExpression(declaration.initializer)) & TypeFlags.Undefined);
|
||||
return annotationIncludesUndefined ? getNonNullableType(annotatedType) : annotatedType;
|
||||
}
|
||||
|
||||
// Return the inferred type for a variable, parameter, or property declaration
|
||||
function getTypeForVariableLikeDeclaration(declaration: VariableLikeDeclaration, includeOptionality: boolean): Type {
|
||||
if (declaration.flags & NodeFlags.JavaScriptFile) {
|
||||
|
@ -3304,7 +3318,8 @@ namespace ts {
|
|||
|
||||
// Use type from type annotation if one is present
|
||||
if (declaration.type) {
|
||||
return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ declaration.questionToken && includeOptionality);
|
||||
const declaredType = removeOptionalityFromAnnotation(getTypeFromTypeNode(declaration.type), declaration);
|
||||
return addOptionality(declaredType, /*optional*/ declaration.questionToken && includeOptionality);
|
||||
}
|
||||
|
||||
if ((compilerOptions.noImplicitAny || declaration.flags & NodeFlags.JavaScriptFile) &&
|
||||
|
@ -5198,6 +5213,12 @@ namespace ts {
|
|||
Debug.assert(parameterIndex >= 0);
|
||||
return parameterIndex >= signature.minArgumentCount;
|
||||
}
|
||||
const iife = getImmediatelyInvokedFunctionExpression(node.parent);
|
||||
if (iife) {
|
||||
return !node.type &&
|
||||
!node.dotDotDotToken &&
|
||||
indexOf((node.parent as SignatureDeclaration).parameters, node) >= iife.arguments.length;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -20702,6 +20723,13 @@ namespace ts {
|
|||
return false;
|
||||
}
|
||||
|
||||
function isRequiredInitializedParameter(parameter: ParameterDeclaration) {
|
||||
return strictNullChecks &&
|
||||
!isOptionalParameter(parameter) &&
|
||||
parameter.initializer &&
|
||||
!(getModifierFlags(parameter) & ModifierFlags.ParameterPropertyModifier);
|
||||
}
|
||||
|
||||
function getNodeCheckFlags(node: Node): NodeCheckFlags {
|
||||
node = getParseTreeNode(node);
|
||||
return node ? getNodeLinks(node).flags : undefined;
|
||||
|
@ -20793,10 +20821,12 @@ namespace ts {
|
|||
function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) {
|
||||
// Get type of the symbol if this is the valid symbol otherwise get type at location
|
||||
const symbol = getSymbolOfNode(declaration);
|
||||
const type = symbol && !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.Signature))
|
||||
let type = symbol && !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.Signature))
|
||||
? getWidenedLiteralType(getTypeOfSymbol(symbol))
|
||||
: unknownType;
|
||||
|
||||
if (flags & TypeFormatFlags.AddUndefined) {
|
||||
type = includeFalsyTypes(type, TypeFlags.Undefined);
|
||||
}
|
||||
getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
|
||||
}
|
||||
|
||||
|
@ -20895,6 +20925,7 @@ namespace ts {
|
|||
isTopLevelValueImportEqualsWithEntityName,
|
||||
isDeclarationVisible,
|
||||
isImplementationOfOverload,
|
||||
isRequiredInitializedParameter,
|
||||
writeTypeOfDeclaration,
|
||||
writeReturnTypeOfSignatureDeclaration,
|
||||
writeTypeOfExpression,
|
||||
|
|
|
@ -324,13 +324,20 @@ namespace ts {
|
|||
function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, type: TypeNode, getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic) {
|
||||
writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic;
|
||||
write(": ");
|
||||
if (type) {
|
||||
|
||||
// use the checker's type, not the declared type,
|
||||
// for non-optional initialized parameters that aren't a parameter property
|
||||
const shouldUseResolverType = declaration.kind === SyntaxKind.Parameter &&
|
||||
resolver.isRequiredInitializedParameter(declaration as ParameterDeclaration);
|
||||
if (type && !shouldUseResolverType) {
|
||||
// Write the type
|
||||
emitType(type);
|
||||
}
|
||||
else {
|
||||
errorNameNode = declaration.name;
|
||||
resolver.writeTypeOfDeclaration(declaration, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue, writer);
|
||||
const format = TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue |
|
||||
(shouldUseResolverType ? TypeFormatFlags.AddUndefined : 0);
|
||||
resolver.writeTypeOfDeclaration(declaration, enclosingDeclaration, format, writer);
|
||||
errorNameNode = undefined;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2474,7 +2474,8 @@
|
|||
InFirstTypeArgument = 0x00000100, // Writing first type argument of the instantiated type
|
||||
InTypeAlias = 0x00000200, // Writing type in type alias declaration
|
||||
UseTypeAliasValue = 0x00000400, // Serialize the type instead of using type-alias. This is needed when we emit declaration file.
|
||||
SuppressAnyReturnType = 0x00000800, // If the return type is any-like, don't offer a return type.
|
||||
SuppressAnyReturnType = 0x00000800, // If the return type is any-like, don't offer a return type.
|
||||
AddUndefined = 0x00001000, // Add undefined to types of initialized, non-optional parameters
|
||||
}
|
||||
|
||||
export const enum SymbolFormatFlags {
|
||||
|
@ -2579,6 +2580,7 @@
|
|||
isDeclarationVisible(node: Declaration): boolean;
|
||||
collectLinkedAliases(node: Identifier): Node[];
|
||||
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean;
|
||||
isRequiredInitializedParameter(node: ParameterDeclaration): boolean;
|
||||
writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
|
||||
writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
|
||||
writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
|
||||
|
|
|
@ -253,8 +253,8 @@ let eleven = (o => o.a(11))({ a: function(n) { return n; } });
|
|||
// missing arguments
|
||||
(function(x, undefined) { return x; })(42);
|
||||
>(function(x, undefined) { return x; })(42) : number
|
||||
>(function(x, undefined) { return x; }) : (x: number, undefined: any) => number
|
||||
>function(x, undefined) { return x; } : (x: number, undefined: any) => number
|
||||
>(function(x, undefined) { return x; }) : (x: number, undefined?: any) => number
|
||||
>function(x, undefined) { return x; } : (x: number, undefined?: any) => number
|
||||
>x : number
|
||||
>undefined : any
|
||||
>x : number
|
||||
|
@ -262,8 +262,8 @@ let eleven = (o => o.a(11))({ a: function(n) { return n; } });
|
|||
|
||||
((x, y, z) => 42)();
|
||||
>((x, y, z) => 42)() : number
|
||||
>((x, y, z) => 42) : (x: any, y: any, z: any) => number
|
||||
>(x, y, z) => 42 : (x: any, y: any, z: any) => number
|
||||
>((x, y, z) => 42) : (x?: any, y?: any, z?: any) => number
|
||||
>(x, y, z) => 42 : (x?: any, y?: any, z?: any) => number
|
||||
>x : any
|
||||
>y : any
|
||||
>z : any
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
//// [defaultParameterAddsUndefinedWithStrictNullChecks.ts]
|
||||
function f(addUndefined1 = "J", addUndefined2?: number) {
|
||||
return addUndefined1.length + (addUndefined2 || 0);
|
||||
}
|
||||
function g(addUndefined = "J", addDefined: number) {
|
||||
return addUndefined.length + addDefined;
|
||||
}
|
||||
let total = f() + f('a', 1) + f('b') + f(undefined, 2);
|
||||
total = g('c', 3) + g(undefined, 4);
|
||||
|
||||
function foo1(x: string = "string", b: number) {
|
||||
x.length;
|
||||
}
|
||||
|
||||
function foo2(x = "string", b: number) {
|
||||
x.length; // ok, should be string
|
||||
}
|
||||
|
||||
function foo3(x: string | undefined = "string", b: number) {
|
||||
x.length; // ok, should be string
|
||||
}
|
||||
|
||||
function foo4(x: string | undefined = undefined, b: number) {
|
||||
x; // should be string | undefined
|
||||
}
|
||||
|
||||
|
||||
|
||||
// .d.ts should have `string | undefined` for foo1, foo2, foo3 and foo4
|
||||
foo1(undefined, 1);
|
||||
foo2(undefined, 1);
|
||||
foo3(undefined, 1);
|
||||
foo4(undefined, 1);
|
||||
|
||||
|
||||
function removeUndefinedButNotFalse(x = true) {
|
||||
if (x === false) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
declare const cond: boolean;
|
||||
function removeNothing(y = cond ? true : undefined) {
|
||||
if (y !== undefined) {
|
||||
if (y === false) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//// [defaultParameterAddsUndefinedWithStrictNullChecks.js]
|
||||
function f(addUndefined1, addUndefined2) {
|
||||
if (addUndefined1 === void 0) { addUndefined1 = "J"; }
|
||||
return addUndefined1.length + (addUndefined2 || 0);
|
||||
}
|
||||
function g(addUndefined, addDefined) {
|
||||
if (addUndefined === void 0) { addUndefined = "J"; }
|
||||
return addUndefined.length + addDefined;
|
||||
}
|
||||
var total = f() + f('a', 1) + f('b') + f(undefined, 2);
|
||||
total = g('c', 3) + g(undefined, 4);
|
||||
function foo1(x, b) {
|
||||
if (x === void 0) { x = "string"; }
|
||||
x.length;
|
||||
}
|
||||
function foo2(x, b) {
|
||||
if (x === void 0) { x = "string"; }
|
||||
x.length; // ok, should be string
|
||||
}
|
||||
function foo3(x, b) {
|
||||
if (x === void 0) { x = "string"; }
|
||||
x.length; // ok, should be string
|
||||
}
|
||||
function foo4(x, b) {
|
||||
if (x === void 0) { x = undefined; }
|
||||
x; // should be string | undefined
|
||||
}
|
||||
// .d.ts should have `string | undefined` for foo1, foo2, foo3 and foo4
|
||||
foo1(undefined, 1);
|
||||
foo2(undefined, 1);
|
||||
foo3(undefined, 1);
|
||||
foo4(undefined, 1);
|
||||
function removeUndefinedButNotFalse(x) {
|
||||
if (x === void 0) { x = true; }
|
||||
if (x === false) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
function removeNothing(y) {
|
||||
if (y === void 0) { y = cond ? true : undefined; }
|
||||
if (y !== undefined) {
|
||||
if (y === false) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//// [defaultParameterAddsUndefinedWithStrictNullChecks.d.ts]
|
||||
declare function f(addUndefined1?: string, addUndefined2?: number): number;
|
||||
declare function g(addUndefined: string | undefined, addDefined: number): number;
|
||||
declare let total: number;
|
||||
declare function foo1(x: string | undefined, b: number): void;
|
||||
declare function foo2(x: string | undefined, b: number): void;
|
||||
declare function foo3(x: string | undefined, b: number): void;
|
||||
declare function foo4(x: string | undefined, b: number): void;
|
||||
declare function removeUndefinedButNotFalse(x?: boolean): false | undefined;
|
||||
declare const cond: boolean;
|
||||
declare function removeNothing(y?: boolean | undefined): boolean;
|
|
@ -0,0 +1,135 @@
|
|||
=== tests/cases/compiler/defaultParameterAddsUndefinedWithStrictNullChecks.ts ===
|
||||
function f(addUndefined1 = "J", addUndefined2?: number) {
|
||||
>f : Symbol(f, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 0, 0))
|
||||
>addUndefined1 : Symbol(addUndefined1, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 0, 11))
|
||||
>addUndefined2 : Symbol(addUndefined2, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 0, 31))
|
||||
|
||||
return addUndefined1.length + (addUndefined2 || 0);
|
||||
>addUndefined1.length : Symbol(String.length, Decl(lib.d.ts, --, --))
|
||||
>addUndefined1 : Symbol(addUndefined1, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 0, 11))
|
||||
>length : Symbol(String.length, Decl(lib.d.ts, --, --))
|
||||
>addUndefined2 : Symbol(addUndefined2, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 0, 31))
|
||||
}
|
||||
function g(addUndefined = "J", addDefined: number) {
|
||||
>g : Symbol(g, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 2, 1))
|
||||
>addUndefined : Symbol(addUndefined, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 3, 11))
|
||||
>addDefined : Symbol(addDefined, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 3, 30))
|
||||
|
||||
return addUndefined.length + addDefined;
|
||||
>addUndefined.length : Symbol(String.length, Decl(lib.d.ts, --, --))
|
||||
>addUndefined : Symbol(addUndefined, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 3, 11))
|
||||
>length : Symbol(String.length, Decl(lib.d.ts, --, --))
|
||||
>addDefined : Symbol(addDefined, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 3, 30))
|
||||
}
|
||||
let total = f() + f('a', 1) + f('b') + f(undefined, 2);
|
||||
>total : Symbol(total, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 6, 3))
|
||||
>f : Symbol(f, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 0, 0))
|
||||
>f : Symbol(f, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 0, 0))
|
||||
>f : Symbol(f, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 0, 0))
|
||||
>f : Symbol(f, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 0, 0))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
total = g('c', 3) + g(undefined, 4);
|
||||
>total : Symbol(total, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 6, 3))
|
||||
>g : Symbol(g, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 2, 1))
|
||||
>g : Symbol(g, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 2, 1))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
function foo1(x: string = "string", b: number) {
|
||||
>foo1 : Symbol(foo1, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 7, 36))
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 9, 14))
|
||||
>b : Symbol(b, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 9, 35))
|
||||
|
||||
x.length;
|
||||
>x.length : Symbol(String.length, Decl(lib.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 9, 14))
|
||||
>length : Symbol(String.length, Decl(lib.d.ts, --, --))
|
||||
}
|
||||
|
||||
function foo2(x = "string", b: number) {
|
||||
>foo2 : Symbol(foo2, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 11, 1))
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 13, 14))
|
||||
>b : Symbol(b, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 13, 27))
|
||||
|
||||
x.length; // ok, should be string
|
||||
>x.length : Symbol(String.length, Decl(lib.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 13, 14))
|
||||
>length : Symbol(String.length, Decl(lib.d.ts, --, --))
|
||||
}
|
||||
|
||||
function foo3(x: string | undefined = "string", b: number) {
|
||||
>foo3 : Symbol(foo3, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 15, 1))
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 17, 14))
|
||||
>b : Symbol(b, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 17, 47))
|
||||
|
||||
x.length; // ok, should be string
|
||||
>x.length : Symbol(String.length, Decl(lib.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 17, 14))
|
||||
>length : Symbol(String.length, Decl(lib.d.ts, --, --))
|
||||
}
|
||||
|
||||
function foo4(x: string | undefined = undefined, b: number) {
|
||||
>foo4 : Symbol(foo4, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 19, 1))
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 21, 14))
|
||||
>undefined : Symbol(undefined)
|
||||
>b : Symbol(b, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 21, 48))
|
||||
|
||||
x; // should be string | undefined
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 21, 14))
|
||||
}
|
||||
|
||||
|
||||
|
||||
// .d.ts should have `string | undefined` for foo1, foo2, foo3 and foo4
|
||||
foo1(undefined, 1);
|
||||
>foo1 : Symbol(foo1, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 7, 36))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
foo2(undefined, 1);
|
||||
>foo2 : Symbol(foo2, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 11, 1))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
foo3(undefined, 1);
|
||||
>foo3 : Symbol(foo3, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 15, 1))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
foo4(undefined, 1);
|
||||
>foo4 : Symbol(foo4, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 19, 1))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
|
||||
function removeUndefinedButNotFalse(x = true) {
|
||||
>removeUndefinedButNotFalse : Symbol(removeUndefinedButNotFalse, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 31, 19))
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 34, 36))
|
||||
|
||||
if (x === false) {
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 34, 36))
|
||||
|
||||
return x;
|
||||
>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 34, 36))
|
||||
}
|
||||
}
|
||||
|
||||
declare const cond: boolean;
|
||||
>cond : Symbol(cond, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 40, 13))
|
||||
|
||||
function removeNothing(y = cond ? true : undefined) {
|
||||
>removeNothing : Symbol(removeNothing, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 40, 28))
|
||||
>y : Symbol(y, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 41, 23))
|
||||
>cond : Symbol(cond, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 40, 13))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
if (y !== undefined) {
|
||||
>y : Symbol(y, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 41, 23))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
if (y === false) {
|
||||
>y : Symbol(y, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 41, 23))
|
||||
|
||||
return y;
|
||||
>y : Symbol(y, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 41, 23))
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
=== tests/cases/compiler/defaultParameterAddsUndefinedWithStrictNullChecks.ts ===
|
||||
function f(addUndefined1 = "J", addUndefined2?: number) {
|
||||
>f : (addUndefined1?: string, addUndefined2?: number | undefined) => number
|
||||
>addUndefined1 : string
|
||||
>"J" : "J"
|
||||
>addUndefined2 : number | undefined
|
||||
|
||||
return addUndefined1.length + (addUndefined2 || 0);
|
||||
>addUndefined1.length + (addUndefined2 || 0) : number
|
||||
>addUndefined1.length : number
|
||||
>addUndefined1 : string
|
||||
>length : number
|
||||
>(addUndefined2 || 0) : number
|
||||
>addUndefined2 || 0 : number
|
||||
>addUndefined2 : number | undefined
|
||||
>0 : 0
|
||||
}
|
||||
function g(addUndefined = "J", addDefined: number) {
|
||||
>g : (addUndefined: string | undefined, addDefined: number) => number
|
||||
>addUndefined : string
|
||||
>"J" : "J"
|
||||
>addDefined : number
|
||||
|
||||
return addUndefined.length + addDefined;
|
||||
>addUndefined.length + addDefined : number
|
||||
>addUndefined.length : number
|
||||
>addUndefined : string
|
||||
>length : number
|
||||
>addDefined : number
|
||||
}
|
||||
let total = f() + f('a', 1) + f('b') + f(undefined, 2);
|
||||
>total : number
|
||||
>f() + f('a', 1) + f('b') + f(undefined, 2) : number
|
||||
>f() + f('a', 1) + f('b') : number
|
||||
>f() + f('a', 1) : number
|
||||
>f() : number
|
||||
>f : (addUndefined1?: string, addUndefined2?: number | undefined) => number
|
||||
>f('a', 1) : number
|
||||
>f : (addUndefined1?: string, addUndefined2?: number | undefined) => number
|
||||
>'a' : "a"
|
||||
>1 : 1
|
||||
>f('b') : number
|
||||
>f : (addUndefined1?: string, addUndefined2?: number | undefined) => number
|
||||
>'b' : "b"
|
||||
>f(undefined, 2) : number
|
||||
>f : (addUndefined1?: string, addUndefined2?: number | undefined) => number
|
||||
>undefined : undefined
|
||||
>2 : 2
|
||||
|
||||
total = g('c', 3) + g(undefined, 4);
|
||||
>total = g('c', 3) + g(undefined, 4) : number
|
||||
>total : number
|
||||
>g('c', 3) + g(undefined, 4) : number
|
||||
>g('c', 3) : number
|
||||
>g : (addUndefined: string | undefined, addDefined: number) => number
|
||||
>'c' : "c"
|
||||
>3 : 3
|
||||
>g(undefined, 4) : number
|
||||
>g : (addUndefined: string | undefined, addDefined: number) => number
|
||||
>undefined : undefined
|
||||
>4 : 4
|
||||
|
||||
function foo1(x: string = "string", b: number) {
|
||||
>foo1 : (x: string | undefined, b: number) => void
|
||||
>x : string
|
||||
>"string" : "string"
|
||||
>b : number
|
||||
|
||||
x.length;
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
}
|
||||
|
||||
function foo2(x = "string", b: number) {
|
||||
>foo2 : (x: string | undefined, b: number) => void
|
||||
>x : string
|
||||
>"string" : "string"
|
||||
>b : number
|
||||
|
||||
x.length; // ok, should be string
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
}
|
||||
|
||||
function foo3(x: string | undefined = "string", b: number) {
|
||||
>foo3 : (x: string | undefined, b: number) => void
|
||||
>x : string
|
||||
>"string" : "string"
|
||||
>b : number
|
||||
|
||||
x.length; // ok, should be string
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
}
|
||||
|
||||
function foo4(x: string | undefined = undefined, b: number) {
|
||||
>foo4 : (x: string | undefined, b: number) => void
|
||||
>x : string | undefined
|
||||
>undefined : undefined
|
||||
>b : number
|
||||
|
||||
x; // should be string | undefined
|
||||
>x : string | undefined
|
||||
}
|
||||
|
||||
|
||||
|
||||
// .d.ts should have `string | undefined` for foo1, foo2, foo3 and foo4
|
||||
foo1(undefined, 1);
|
||||
>foo1(undefined, 1) : void
|
||||
>foo1 : (x: string | undefined, b: number) => void
|
||||
>undefined : undefined
|
||||
>1 : 1
|
||||
|
||||
foo2(undefined, 1);
|
||||
>foo2(undefined, 1) : void
|
||||
>foo2 : (x: string | undefined, b: number) => void
|
||||
>undefined : undefined
|
||||
>1 : 1
|
||||
|
||||
foo3(undefined, 1);
|
||||
>foo3(undefined, 1) : void
|
||||
>foo3 : (x: string | undefined, b: number) => void
|
||||
>undefined : undefined
|
||||
>1 : 1
|
||||
|
||||
foo4(undefined, 1);
|
||||
>foo4(undefined, 1) : void
|
||||
>foo4 : (x: string | undefined, b: number) => void
|
||||
>undefined : undefined
|
||||
>1 : 1
|
||||
|
||||
|
||||
function removeUndefinedButNotFalse(x = true) {
|
||||
>removeUndefinedButNotFalse : (x?: boolean) => false | undefined
|
||||
>x : boolean
|
||||
>true : true
|
||||
|
||||
if (x === false) {
|
||||
>x === false : boolean
|
||||
>x : boolean
|
||||
>false : false
|
||||
|
||||
return x;
|
||||
>x : false
|
||||
}
|
||||
}
|
||||
|
||||
declare const cond: boolean;
|
||||
>cond : boolean
|
||||
|
||||
function removeNothing(y = cond ? true : undefined) {
|
||||
>removeNothing : (y?: boolean | undefined) => boolean
|
||||
>y : boolean | undefined
|
||||
>cond ? true : undefined : true | undefined
|
||||
>cond : boolean
|
||||
>true : true
|
||||
>undefined : undefined
|
||||
|
||||
if (y !== undefined) {
|
||||
>y !== undefined : boolean
|
||||
>y : boolean | undefined
|
||||
>undefined : undefined
|
||||
|
||||
if (y === false) {
|
||||
>y === false : boolean
|
||||
>y : boolean
|
||||
>false : false
|
||||
|
||||
return y;
|
||||
>y : false
|
||||
}
|
||||
}
|
||||
return true;
|
||||
>true : true
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
// @strictNullChecks: true
|
||||
// @declaration: true
|
||||
function f(addUndefined1 = "J", addUndefined2?: number) {
|
||||
return addUndefined1.length + (addUndefined2 || 0);
|
||||
}
|
||||
function g(addUndefined = "J", addDefined: number) {
|
||||
return addUndefined.length + addDefined;
|
||||
}
|
||||
let total = f() + f('a', 1) + f('b') + f(undefined, 2);
|
||||
total = g('c', 3) + g(undefined, 4);
|
||||
|
||||
function foo1(x: string = "string", b: number) {
|
||||
x.length;
|
||||
}
|
||||
|
||||
function foo2(x = "string", b: number) {
|
||||
x.length; // ok, should be string
|
||||
}
|
||||
|
||||
function foo3(x: string | undefined = "string", b: number) {
|
||||
x.length; // ok, should be string
|
||||
}
|
||||
|
||||
function foo4(x: string | undefined = undefined, b: number) {
|
||||
x; // should be string | undefined
|
||||
}
|
||||
|
||||
|
||||
|
||||
// .d.ts should have `string | undefined` for foo1, foo2, foo3 and foo4
|
||||
foo1(undefined, 1);
|
||||
foo2(undefined, 1);
|
||||
foo3(undefined, 1);
|
||||
foo4(undefined, 1);
|
||||
|
||||
|
||||
function removeUndefinedButNotFalse(x = true) {
|
||||
if (x === false) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
declare const cond: boolean;
|
||||
function removeNothing(y = cond ? true : undefined) {
|
||||
if (y !== undefined) {
|
||||
if (y === false) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
5
tests/cases/fourslash/quickInfoDisplayPartsIife.ts
Normal file
5
tests/cases/fourslash/quickInfoDisplayPartsIife.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
/// <reference path='fourslash.ts'/>
|
||||
// @strictNullChecks: true
|
||||
////var iife = (function foo/*1*/(x, y) { return x })(12);
|
||||
|
||||
verify.quickInfoAt('1', '(local function) foo(x: number, y?: undefined): number');
|
Loading…
Reference in a new issue