diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c3b1cd4258b..533bedc70a1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11181,7 +11181,7 @@ namespace ts { // type, we include 'undefined' in the type. Similarly, when creating a non-optional property in strictNullChecks // mode, if the underlying property is optional we remove 'undefined' from the type. let type = strictNullChecks && symbol.flags & SymbolFlags.Optional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType, /*isProperty*/ true) : - symbol.checkFlags & CheckFlags.StripOptional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) : + symbol.checkFlags & CheckFlags.StripOptional ? removeMissingOrUndefinedType(propType) : propType; if (!popTypeResolution()) { error(currentNode, Diagnostics.Type_of_property_0_circularly_references_itself_in_mapped_type_1, symbolToString(symbol), typeToString(mappedType)); @@ -12045,7 +12045,7 @@ namespace ts { for (const prop of getPropertiesOfType(type)) { if (kind === IndexKind.String || isNumericLiteralName(prop.escapedName)) { const propType = getTypeOfSymbol(prop); - propTypes.push(prop.flags & SymbolFlags.Optional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) : propType); + propTypes.push(prop.flags & SymbolFlags.Optional ? removeMissingOrUndefinedType(propType) : propType); } } if (kind === IndexKind.String) { @@ -20331,12 +20331,8 @@ namespace ts { return strictNullChecks ? getUnionType([type, optionalType]) : type; } - function isNotOptionalTypeMarker(type: Type) { - return type !== optionalType; - } - function removeOptionalTypeMarker(type: Type): Type { - return strictNullChecks ? filterType(type, isNotOptionalTypeMarker) : type; + return strictNullChecks ? removeType(type, optionalType) : type; } function propagateOptionalTypeMarker(type: Type, node: OptionalChain, wasOptional: boolean) { @@ -20350,13 +20346,17 @@ namespace ts { } function removeMissingType(type: Type, isOptional: boolean) { - return strictOptionalProperties && isOptional ? filterType(type, t => t !== missingType) : type; + return strictOptionalProperties && isOptional ? removeType(type, missingType) : type; } function containsMissingType(type: Type) { return strictOptionalProperties && (type === missingType || type.flags & TypeFlags.Union && containsType((type as UnionType).types, missingType)); } + function removeMissingOrUndefinedType(type: Type): Type { + return strictOptionalProperties ? removeType(type, missingType) : getTypeWithFacts(type, TypeFacts.NEUndefined); + } + /** * Is source potentially coercible to target type under `==`. * Assumes that `source` is a constituent of a union, hence @@ -22562,6 +22562,10 @@ namespace ts { return type.flags & TypeFlags.Never || f(type) ? type : neverType; } + function removeType(type: Type, targetType: Type) { + return filterType(type, t => t !== targetType); + } + function countTypes(type: Type) { return type.flags & TypeFlags.Union ? (type as UnionType).types.length : 1; } @@ -23460,7 +23464,7 @@ namespace ts { const candidate = getConstituentTypeForKeyType(type as UnionType, getTypeOfExpression(value)); if (candidate) { return operator === (assumeTrue ? SyntaxKind.EqualsEqualsEqualsToken : SyntaxKind.ExclamationEqualsEqualsToken) ? candidate : - isUnitType(getTypeOfPropertyOfType(candidate, keyPropertyName) || unknownType) ? filterType(type, t => t !== candidate) : + isUnitType(getTypeOfPropertyOfType(candidate, keyPropertyName) || unknownType) ? removeType(type, candidate) : type; } } diff --git a/tests/baselines/reference/inferenceOptionalProperties.js b/tests/baselines/reference/inferenceOptionalProperties.js new file mode 100644 index 00000000000..d762677061b --- /dev/null +++ b/tests/baselines/reference/inferenceOptionalProperties.js @@ -0,0 +1,108 @@ +//// [inferenceOptionalProperties.ts] +declare function test(x: { [key: string]: T }): T; + +declare let x1: { a?: string, b?: number }; +declare let x2: { a?: string, b?: number | undefined }; + +const y1 = test(x1); +const y2 = test(x2); + +var v1: Required<{ a?: string, b?: number }>; +var v1: { a: string, b: number }; + +var v2: Required<{ a?: string, b?: number | undefined }>; +var v2: { a: string, b: number | undefined }; + +var v3: Partial<{ a: string, b: string }>; +var v3: { a?: string, b?: string }; + +var v4: Partial<{ a: string, b: string | undefined }>; +var v4: { a?: string, b?: string | undefined }; + +var v5: Required>; +var v5: { a: string, b: string }; + +var v6: Required>; +var v6: { a: string, b: string | undefined }; + + +//// [inferenceOptionalProperties.js] +"use strict"; +var y1 = test(x1); +var y2 = test(x2); +var v1; +var v1; +var v2; +var v2; +var v3; +var v3; +var v4; +var v4; +var v5; +var v5; +var v6; +var v6; + + +//// [inferenceOptionalProperties.d.ts] +declare function test(x: { + [key: string]: T; +}): T; +declare let x1: { + a?: string; + b?: number; +}; +declare let x2: { + a?: string; + b?: number | undefined; +}; +declare const y1: string | number; +declare const y2: string | number | undefined; +declare var v1: Required<{ + a?: string; + b?: number; +}>; +declare var v1: { + a: string; + b: number; +}; +declare var v2: Required<{ + a?: string; + b?: number | undefined; +}>; +declare var v2: { + a: string; + b: number | undefined; +}; +declare var v3: Partial<{ + a: string; + b: string; +}>; +declare var v3: { + a?: string; + b?: string; +}; +declare var v4: Partial<{ + a: string; + b: string | undefined; +}>; +declare var v4: { + a?: string; + b?: string | undefined; +}; +declare var v5: Required>; +declare var v5: { + a: string; + b: string; +}; +declare var v6: Required>; +declare var v6: { + a: string; + b: string | undefined; +}; diff --git a/tests/baselines/reference/inferenceOptionalProperties.symbols b/tests/baselines/reference/inferenceOptionalProperties.symbols new file mode 100644 index 00000000000..f5055db8863 --- /dev/null +++ b/tests/baselines/reference/inferenceOptionalProperties.symbols @@ -0,0 +1,97 @@ +=== tests/cases/compiler/inferenceOptionalProperties.ts === +declare function test(x: { [key: string]: T }): T; +>test : Symbol(test, Decl(inferenceOptionalProperties.ts, 0, 0)) +>T : Symbol(T, Decl(inferenceOptionalProperties.ts, 0, 22)) +>x : Symbol(x, Decl(inferenceOptionalProperties.ts, 0, 25)) +>key : Symbol(key, Decl(inferenceOptionalProperties.ts, 0, 31)) +>T : Symbol(T, Decl(inferenceOptionalProperties.ts, 0, 22)) +>T : Symbol(T, Decl(inferenceOptionalProperties.ts, 0, 22)) + +declare let x1: { a?: string, b?: number }; +>x1 : Symbol(x1, Decl(inferenceOptionalProperties.ts, 2, 11)) +>a : Symbol(a, Decl(inferenceOptionalProperties.ts, 2, 17)) +>b : Symbol(b, Decl(inferenceOptionalProperties.ts, 2, 29)) + +declare let x2: { a?: string, b?: number | undefined }; +>x2 : Symbol(x2, Decl(inferenceOptionalProperties.ts, 3, 11)) +>a : Symbol(a, Decl(inferenceOptionalProperties.ts, 3, 17)) +>b : Symbol(b, Decl(inferenceOptionalProperties.ts, 3, 29)) + +const y1 = test(x1); +>y1 : Symbol(y1, Decl(inferenceOptionalProperties.ts, 5, 5)) +>test : Symbol(test, Decl(inferenceOptionalProperties.ts, 0, 0)) +>x1 : Symbol(x1, Decl(inferenceOptionalProperties.ts, 2, 11)) + +const y2 = test(x2); +>y2 : Symbol(y2, Decl(inferenceOptionalProperties.ts, 6, 5)) +>test : Symbol(test, Decl(inferenceOptionalProperties.ts, 0, 0)) +>x2 : Symbol(x2, Decl(inferenceOptionalProperties.ts, 3, 11)) + +var v1: Required<{ a?: string, b?: number }>; +>v1 : Symbol(v1, Decl(inferenceOptionalProperties.ts, 8, 3), Decl(inferenceOptionalProperties.ts, 9, 3)) +>Required : Symbol(Required, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(inferenceOptionalProperties.ts, 8, 18)) +>b : Symbol(b, Decl(inferenceOptionalProperties.ts, 8, 30)) + +var v1: { a: string, b: number }; +>v1 : Symbol(v1, Decl(inferenceOptionalProperties.ts, 8, 3), Decl(inferenceOptionalProperties.ts, 9, 3)) +>a : Symbol(a, Decl(inferenceOptionalProperties.ts, 9, 9)) +>b : Symbol(b, Decl(inferenceOptionalProperties.ts, 9, 20)) + +var v2: Required<{ a?: string, b?: number | undefined }>; +>v2 : Symbol(v2, Decl(inferenceOptionalProperties.ts, 11, 3), Decl(inferenceOptionalProperties.ts, 12, 3)) +>Required : Symbol(Required, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(inferenceOptionalProperties.ts, 11, 18)) +>b : Symbol(b, Decl(inferenceOptionalProperties.ts, 11, 30)) + +var v2: { a: string, b: number | undefined }; +>v2 : Symbol(v2, Decl(inferenceOptionalProperties.ts, 11, 3), Decl(inferenceOptionalProperties.ts, 12, 3)) +>a : Symbol(a, Decl(inferenceOptionalProperties.ts, 12, 9)) +>b : Symbol(b, Decl(inferenceOptionalProperties.ts, 12, 20)) + +var v3: Partial<{ a: string, b: string }>; +>v3 : Symbol(v3, Decl(inferenceOptionalProperties.ts, 14, 3), Decl(inferenceOptionalProperties.ts, 15, 3)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(inferenceOptionalProperties.ts, 14, 17)) +>b : Symbol(b, Decl(inferenceOptionalProperties.ts, 14, 28)) + +var v3: { a?: string, b?: string }; +>v3 : Symbol(v3, Decl(inferenceOptionalProperties.ts, 14, 3), Decl(inferenceOptionalProperties.ts, 15, 3)) +>a : Symbol(a, Decl(inferenceOptionalProperties.ts, 15, 9)) +>b : Symbol(b, Decl(inferenceOptionalProperties.ts, 15, 21)) + +var v4: Partial<{ a: string, b: string | undefined }>; +>v4 : Symbol(v4, Decl(inferenceOptionalProperties.ts, 17, 3), Decl(inferenceOptionalProperties.ts, 18, 3)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(inferenceOptionalProperties.ts, 17, 17)) +>b : Symbol(b, Decl(inferenceOptionalProperties.ts, 17, 28)) + +var v4: { a?: string, b?: string | undefined }; +>v4 : Symbol(v4, Decl(inferenceOptionalProperties.ts, 17, 3), Decl(inferenceOptionalProperties.ts, 18, 3)) +>a : Symbol(a, Decl(inferenceOptionalProperties.ts, 18, 9)) +>b : Symbol(b, Decl(inferenceOptionalProperties.ts, 18, 21)) + +var v5: Required>; +>v5 : Symbol(v5, Decl(inferenceOptionalProperties.ts, 20, 3), Decl(inferenceOptionalProperties.ts, 21, 3)) +>Required : Symbol(Required, Decl(lib.es5.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(inferenceOptionalProperties.ts, 20, 26)) +>b : Symbol(b, Decl(inferenceOptionalProperties.ts, 20, 37)) + +var v5: { a: string, b: string }; +>v5 : Symbol(v5, Decl(inferenceOptionalProperties.ts, 20, 3), Decl(inferenceOptionalProperties.ts, 21, 3)) +>a : Symbol(a, Decl(inferenceOptionalProperties.ts, 21, 9)) +>b : Symbol(b, Decl(inferenceOptionalProperties.ts, 21, 20)) + +var v6: Required>; +>v6 : Symbol(v6, Decl(inferenceOptionalProperties.ts, 23, 3), Decl(inferenceOptionalProperties.ts, 24, 3)) +>Required : Symbol(Required, Decl(lib.es5.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(inferenceOptionalProperties.ts, 23, 26)) +>b : Symbol(b, Decl(inferenceOptionalProperties.ts, 23, 37)) + +var v6: { a: string, b: string | undefined }; +>v6 : Symbol(v6, Decl(inferenceOptionalProperties.ts, 23, 3), Decl(inferenceOptionalProperties.ts, 24, 3)) +>a : Symbol(a, Decl(inferenceOptionalProperties.ts, 24, 9)) +>b : Symbol(b, Decl(inferenceOptionalProperties.ts, 24, 20)) + diff --git a/tests/baselines/reference/inferenceOptionalProperties.types b/tests/baselines/reference/inferenceOptionalProperties.types new file mode 100644 index 00000000000..f5cd9f97caa --- /dev/null +++ b/tests/baselines/reference/inferenceOptionalProperties.types @@ -0,0 +1,88 @@ +=== tests/cases/compiler/inferenceOptionalProperties.ts === +declare function test(x: { [key: string]: T }): T; +>test : (x: { [key: string]: T; }) => T +>x : { [key: string]: T; } +>key : string + +declare let x1: { a?: string, b?: number }; +>x1 : { a?: string; b?: number; } +>a : string | undefined +>b : number | undefined + +declare let x2: { a?: string, b?: number | undefined }; +>x2 : { a?: string; b?: number | undefined; } +>a : string | undefined +>b : number | undefined + +const y1 = test(x1); +>y1 : string | number +>test(x1) : string | number +>test : (x: { [key: string]: T; }) => T +>x1 : { a?: string; b?: number; } + +const y2 = test(x2); +>y2 : string | number | undefined +>test(x2) : string | number | undefined +>test : (x: { [key: string]: T; }) => T +>x2 : { a?: string; b?: number | undefined; } + +var v1: Required<{ a?: string, b?: number }>; +>v1 : Required<{ a?: string; b?: number; }> +>a : string | undefined +>b : number | undefined + +var v1: { a: string, b: number }; +>v1 : Required<{ a?: string; b?: number; }> +>a : string +>b : number + +var v2: Required<{ a?: string, b?: number | undefined }>; +>v2 : Required<{ a?: string; b?: number | undefined; }> +>a : string | undefined +>b : number | undefined + +var v2: { a: string, b: number | undefined }; +>v2 : Required<{ a?: string; b?: number | undefined; }> +>a : string +>b : number | undefined + +var v3: Partial<{ a: string, b: string }>; +>v3 : Partial<{ a: string; b: string; }> +>a : string +>b : string + +var v3: { a?: string, b?: string }; +>v3 : Partial<{ a: string; b: string; }> +>a : string | undefined +>b : string | undefined + +var v4: Partial<{ a: string, b: string | undefined }>; +>v4 : Partial<{ a: string; b: string | undefined; }> +>a : string +>b : string | undefined + +var v4: { a?: string, b?: string | undefined }; +>v4 : Partial<{ a: string; b: string | undefined; }> +>a : string | undefined +>b : string | undefined + +var v5: Required>; +>v5 : Required> +>a : string +>b : string + +var v5: { a: string, b: string }; +>v5 : Required> +>a : string +>b : string + +var v6: Required>; +>v6 : Required> +>a : string +>b : string | undefined + +var v6: { a: string, b: string | undefined }; +>v6 : Required> +>a : string +>b : string | undefined + diff --git a/tests/baselines/reference/inferenceOptionalPropertiesStrict.js b/tests/baselines/reference/inferenceOptionalPropertiesStrict.js new file mode 100644 index 00000000000..7a7fb1728c6 --- /dev/null +++ b/tests/baselines/reference/inferenceOptionalPropertiesStrict.js @@ -0,0 +1,108 @@ +//// [inferenceOptionalPropertiesStrict.ts] +declare function test(x: { [key: string]: T }): T; + +declare let x1: { a?: string, b?: number }; +declare let x2: { a?: string, b?: number | undefined }; + +const y1 = test(x1); +const y2 = test(x2); + +var v1: Required<{ a?: string, b?: number }>; +var v1: { a: string, b: number }; + +var v2: Required<{ a?: string, b?: number | undefined }>; +var v2: { a: string, b: number | undefined }; + +var v3: Partial<{ a: string, b: string }>; +var v3: { a?: string, b?: string }; + +var v4: Partial<{ a: string, b: string | undefined }>; +var v4: { a?: string, b?: string | undefined }; + +var v5: Required>; +var v5: { a: string, b: string }; + +var v6: Required>; +var v6: { a: string, b: string | undefined }; + + +//// [inferenceOptionalPropertiesStrict.js] +"use strict"; +var y1 = test(x1); +var y2 = test(x2); +var v1; +var v1; +var v2; +var v2; +var v3; +var v3; +var v4; +var v4; +var v5; +var v5; +var v6; +var v6; + + +//// [inferenceOptionalPropertiesStrict.d.ts] +declare function test(x: { + [key: string]: T; +}): T; +declare let x1: { + a?: string; + b?: number; +}; +declare let x2: { + a?: string; + b?: number | undefined; +}; +declare const y1: string | number; +declare const y2: string | number | undefined; +declare var v1: Required<{ + a?: string; + b?: number; +}>; +declare var v1: { + a: string; + b: number; +}; +declare var v2: Required<{ + a?: string; + b?: number | undefined; +}>; +declare var v2: { + a: string; + b: number | undefined; +}; +declare var v3: Partial<{ + a: string; + b: string; +}>; +declare var v3: { + a?: string; + b?: string; +}; +declare var v4: Partial<{ + a: string; + b: string | undefined; +}>; +declare var v4: { + a?: string; + b?: string | undefined; +}; +declare var v5: Required>; +declare var v5: { + a: string; + b: string; +}; +declare var v6: Required>; +declare var v6: { + a: string; + b: string | undefined; +}; diff --git a/tests/baselines/reference/inferenceOptionalPropertiesStrict.symbols b/tests/baselines/reference/inferenceOptionalPropertiesStrict.symbols new file mode 100644 index 00000000000..2d7b232e7f7 --- /dev/null +++ b/tests/baselines/reference/inferenceOptionalPropertiesStrict.symbols @@ -0,0 +1,97 @@ +=== tests/cases/compiler/inferenceOptionalPropertiesStrict.ts === +declare function test(x: { [key: string]: T }): T; +>test : Symbol(test, Decl(inferenceOptionalPropertiesStrict.ts, 0, 0)) +>T : Symbol(T, Decl(inferenceOptionalPropertiesStrict.ts, 0, 22)) +>x : Symbol(x, Decl(inferenceOptionalPropertiesStrict.ts, 0, 25)) +>key : Symbol(key, Decl(inferenceOptionalPropertiesStrict.ts, 0, 31)) +>T : Symbol(T, Decl(inferenceOptionalPropertiesStrict.ts, 0, 22)) +>T : Symbol(T, Decl(inferenceOptionalPropertiesStrict.ts, 0, 22)) + +declare let x1: { a?: string, b?: number }; +>x1 : Symbol(x1, Decl(inferenceOptionalPropertiesStrict.ts, 2, 11)) +>a : Symbol(a, Decl(inferenceOptionalPropertiesStrict.ts, 2, 17)) +>b : Symbol(b, Decl(inferenceOptionalPropertiesStrict.ts, 2, 29)) + +declare let x2: { a?: string, b?: number | undefined }; +>x2 : Symbol(x2, Decl(inferenceOptionalPropertiesStrict.ts, 3, 11)) +>a : Symbol(a, Decl(inferenceOptionalPropertiesStrict.ts, 3, 17)) +>b : Symbol(b, Decl(inferenceOptionalPropertiesStrict.ts, 3, 29)) + +const y1 = test(x1); +>y1 : Symbol(y1, Decl(inferenceOptionalPropertiesStrict.ts, 5, 5)) +>test : Symbol(test, Decl(inferenceOptionalPropertiesStrict.ts, 0, 0)) +>x1 : Symbol(x1, Decl(inferenceOptionalPropertiesStrict.ts, 2, 11)) + +const y2 = test(x2); +>y2 : Symbol(y2, Decl(inferenceOptionalPropertiesStrict.ts, 6, 5)) +>test : Symbol(test, Decl(inferenceOptionalPropertiesStrict.ts, 0, 0)) +>x2 : Symbol(x2, Decl(inferenceOptionalPropertiesStrict.ts, 3, 11)) + +var v1: Required<{ a?: string, b?: number }>; +>v1 : Symbol(v1, Decl(inferenceOptionalPropertiesStrict.ts, 8, 3), Decl(inferenceOptionalPropertiesStrict.ts, 9, 3)) +>Required : Symbol(Required, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(inferenceOptionalPropertiesStrict.ts, 8, 18)) +>b : Symbol(b, Decl(inferenceOptionalPropertiesStrict.ts, 8, 30)) + +var v1: { a: string, b: number }; +>v1 : Symbol(v1, Decl(inferenceOptionalPropertiesStrict.ts, 8, 3), Decl(inferenceOptionalPropertiesStrict.ts, 9, 3)) +>a : Symbol(a, Decl(inferenceOptionalPropertiesStrict.ts, 9, 9)) +>b : Symbol(b, Decl(inferenceOptionalPropertiesStrict.ts, 9, 20)) + +var v2: Required<{ a?: string, b?: number | undefined }>; +>v2 : Symbol(v2, Decl(inferenceOptionalPropertiesStrict.ts, 11, 3), Decl(inferenceOptionalPropertiesStrict.ts, 12, 3)) +>Required : Symbol(Required, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(inferenceOptionalPropertiesStrict.ts, 11, 18)) +>b : Symbol(b, Decl(inferenceOptionalPropertiesStrict.ts, 11, 30)) + +var v2: { a: string, b: number | undefined }; +>v2 : Symbol(v2, Decl(inferenceOptionalPropertiesStrict.ts, 11, 3), Decl(inferenceOptionalPropertiesStrict.ts, 12, 3)) +>a : Symbol(a, Decl(inferenceOptionalPropertiesStrict.ts, 12, 9)) +>b : Symbol(b, Decl(inferenceOptionalPropertiesStrict.ts, 12, 20)) + +var v3: Partial<{ a: string, b: string }>; +>v3 : Symbol(v3, Decl(inferenceOptionalPropertiesStrict.ts, 14, 3), Decl(inferenceOptionalPropertiesStrict.ts, 15, 3)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(inferenceOptionalPropertiesStrict.ts, 14, 17)) +>b : Symbol(b, Decl(inferenceOptionalPropertiesStrict.ts, 14, 28)) + +var v3: { a?: string, b?: string }; +>v3 : Symbol(v3, Decl(inferenceOptionalPropertiesStrict.ts, 14, 3), Decl(inferenceOptionalPropertiesStrict.ts, 15, 3)) +>a : Symbol(a, Decl(inferenceOptionalPropertiesStrict.ts, 15, 9)) +>b : Symbol(b, Decl(inferenceOptionalPropertiesStrict.ts, 15, 21)) + +var v4: Partial<{ a: string, b: string | undefined }>; +>v4 : Symbol(v4, Decl(inferenceOptionalPropertiesStrict.ts, 17, 3), Decl(inferenceOptionalPropertiesStrict.ts, 18, 3)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(inferenceOptionalPropertiesStrict.ts, 17, 17)) +>b : Symbol(b, Decl(inferenceOptionalPropertiesStrict.ts, 17, 28)) + +var v4: { a?: string, b?: string | undefined }; +>v4 : Symbol(v4, Decl(inferenceOptionalPropertiesStrict.ts, 17, 3), Decl(inferenceOptionalPropertiesStrict.ts, 18, 3)) +>a : Symbol(a, Decl(inferenceOptionalPropertiesStrict.ts, 18, 9)) +>b : Symbol(b, Decl(inferenceOptionalPropertiesStrict.ts, 18, 21)) + +var v5: Required>; +>v5 : Symbol(v5, Decl(inferenceOptionalPropertiesStrict.ts, 20, 3), Decl(inferenceOptionalPropertiesStrict.ts, 21, 3)) +>Required : Symbol(Required, Decl(lib.es5.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(inferenceOptionalPropertiesStrict.ts, 20, 26)) +>b : Symbol(b, Decl(inferenceOptionalPropertiesStrict.ts, 20, 37)) + +var v5: { a: string, b: string }; +>v5 : Symbol(v5, Decl(inferenceOptionalPropertiesStrict.ts, 20, 3), Decl(inferenceOptionalPropertiesStrict.ts, 21, 3)) +>a : Symbol(a, Decl(inferenceOptionalPropertiesStrict.ts, 21, 9)) +>b : Symbol(b, Decl(inferenceOptionalPropertiesStrict.ts, 21, 20)) + +var v6: Required>; +>v6 : Symbol(v6, Decl(inferenceOptionalPropertiesStrict.ts, 23, 3), Decl(inferenceOptionalPropertiesStrict.ts, 24, 3)) +>Required : Symbol(Required, Decl(lib.es5.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(inferenceOptionalPropertiesStrict.ts, 23, 26)) +>b : Symbol(b, Decl(inferenceOptionalPropertiesStrict.ts, 23, 37)) + +var v6: { a: string, b: string | undefined }; +>v6 : Symbol(v6, Decl(inferenceOptionalPropertiesStrict.ts, 23, 3), Decl(inferenceOptionalPropertiesStrict.ts, 24, 3)) +>a : Symbol(a, Decl(inferenceOptionalPropertiesStrict.ts, 24, 9)) +>b : Symbol(b, Decl(inferenceOptionalPropertiesStrict.ts, 24, 20)) + diff --git a/tests/baselines/reference/inferenceOptionalPropertiesStrict.types b/tests/baselines/reference/inferenceOptionalPropertiesStrict.types new file mode 100644 index 00000000000..852ea98d3ba --- /dev/null +++ b/tests/baselines/reference/inferenceOptionalPropertiesStrict.types @@ -0,0 +1,88 @@ +=== tests/cases/compiler/inferenceOptionalPropertiesStrict.ts === +declare function test(x: { [key: string]: T }): T; +>test : (x: { [key: string]: T; }) => T +>x : { [key: string]: T; } +>key : string + +declare let x1: { a?: string, b?: number }; +>x1 : { a?: string; b?: number; } +>a : string | undefined +>b : number | undefined + +declare let x2: { a?: string, b?: number | undefined }; +>x2 : { a?: string; b?: number | undefined; } +>a : string | undefined +>b : number | undefined + +const y1 = test(x1); +>y1 : string | number +>test(x1) : string | number +>test : (x: { [key: string]: T; }) => T +>x1 : { a?: string; b?: number; } + +const y2 = test(x2); +>y2 : string | number | undefined +>test(x2) : string | number | undefined +>test : (x: { [key: string]: T; }) => T +>x2 : { a?: string; b?: number | undefined; } + +var v1: Required<{ a?: string, b?: number }>; +>v1 : Required<{ a?: string; b?: number; }> +>a : string | undefined +>b : number | undefined + +var v1: { a: string, b: number }; +>v1 : Required<{ a?: string; b?: number; }> +>a : string +>b : number + +var v2: Required<{ a?: string, b?: number | undefined }>; +>v2 : Required<{ a?: string; b?: number | undefined; }> +>a : string | undefined +>b : number | undefined + +var v2: { a: string, b: number | undefined }; +>v2 : Required<{ a?: string; b?: number | undefined; }> +>a : string +>b : number | undefined + +var v3: Partial<{ a: string, b: string }>; +>v3 : Partial<{ a: string; b: string; }> +>a : string +>b : string + +var v3: { a?: string, b?: string }; +>v3 : Partial<{ a: string; b: string; }> +>a : string | undefined +>b : string | undefined + +var v4: Partial<{ a: string, b: string | undefined }>; +>v4 : Partial<{ a: string; b: string | undefined; }> +>a : string +>b : string | undefined + +var v4: { a?: string, b?: string | undefined }; +>v4 : Partial<{ a: string; b: string | undefined; }> +>a : string | undefined +>b : string | undefined + +var v5: Required>; +>v5 : Required> +>a : string +>b : string + +var v5: { a: string, b: string }; +>v5 : Required> +>a : string +>b : string + +var v6: Required>; +>v6 : Required> +>a : string +>b : string | undefined + +var v6: { a: string, b: string | undefined }; +>v6 : Required> +>a : string +>b : string | undefined + diff --git a/tests/baselines/reference/inferenceOptionalPropertiesToIndexSignatures.types b/tests/baselines/reference/inferenceOptionalPropertiesToIndexSignatures.types index 8c5ce88ac26..0d8e4bda7c5 100644 --- a/tests/baselines/reference/inferenceOptionalPropertiesToIndexSignatures.types +++ b/tests/baselines/reference/inferenceOptionalPropertiesToIndexSignatures.types @@ -43,8 +43,8 @@ let a3 = foo(x3); // string | number >x3 : { a: string; b?: number; } let a4 = foo(x4); // string | number ->a4 : string | number ->foo(x4) : string | number +>a4 : string | number | undefined +>foo(x4) : string | number | undefined >foo : (obj: { [x: string]: T; }) => T >x4 : { a: string; b?: number | undefined; } diff --git a/tests/cases/compiler/inferenceOptionalProperties.ts b/tests/cases/compiler/inferenceOptionalProperties.ts new file mode 100644 index 00000000000..f1d4fec0903 --- /dev/null +++ b/tests/cases/compiler/inferenceOptionalProperties.ts @@ -0,0 +1,29 @@ +// @strict: true +// @strictOptionalProperties: true +// @declaration: true + +declare function test(x: { [key: string]: T }): T; + +declare let x1: { a?: string, b?: number }; +declare let x2: { a?: string, b?: number | undefined }; + +const y1 = test(x1); +const y2 = test(x2); + +var v1: Required<{ a?: string, b?: number }>; +var v1: { a: string, b: number }; + +var v2: Required<{ a?: string, b?: number | undefined }>; +var v2: { a: string, b: number | undefined }; + +var v3: Partial<{ a: string, b: string }>; +var v3: { a?: string, b?: string }; + +var v4: Partial<{ a: string, b: string | undefined }>; +var v4: { a?: string, b?: string | undefined }; + +var v5: Required>; +var v5: { a: string, b: string }; + +var v6: Required>; +var v6: { a: string, b: string | undefined }; diff --git a/tests/cases/compiler/inferenceOptionalPropertiesStrict.ts b/tests/cases/compiler/inferenceOptionalPropertiesStrict.ts new file mode 100644 index 00000000000..f1d4fec0903 --- /dev/null +++ b/tests/cases/compiler/inferenceOptionalPropertiesStrict.ts @@ -0,0 +1,29 @@ +// @strict: true +// @strictOptionalProperties: true +// @declaration: true + +declare function test(x: { [key: string]: T }): T; + +declare let x1: { a?: string, b?: number }; +declare let x2: { a?: string, b?: number | undefined }; + +const y1 = test(x1); +const y2 = test(x2); + +var v1: Required<{ a?: string, b?: number }>; +var v1: { a: string, b: number }; + +var v2: Required<{ a?: string, b?: number | undefined }>; +var v2: { a: string, b: number | undefined }; + +var v3: Partial<{ a: string, b: string }>; +var v3: { a?: string, b?: string }; + +var v4: Partial<{ a: string, b: string | undefined }>; +var v4: { a?: string, b?: string | undefined }; + +var v5: Required>; +var v5: { a: string, b: string }; + +var v6: Required>; +var v6: { a: string, b: string | undefined };