diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index dfd479127202c..c75de269a18d3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7354,7 +7354,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function typeReferenceToTypeNode(type: TypeReference) { - let typeArguments: readonly Type[] = getTypeArguments(type); + const typeArguments = getTypeArguments(type); if (type.target === globalArrayType || type.target === globalReadonlyArrayType) { if (context.flags & NodeBuilderFlags.WriteArrayAsGenericType) { const typeArgumentNode = typeToTypeNodeHelper(typeArguments[0], context); @@ -7365,7 +7365,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return type.target === globalArrayType ? arrayType : factory.createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, arrayType); } else if (type.target.objectFlags & ObjectFlags.Tuple) { - typeArguments = sameMap(typeArguments, (t, i) => removeMissingType(t, !!((type.target as TupleType).elementFlags[i] & ElementFlags.Optional))); if (typeArguments.length > 0) { const arity = getTypeReferenceArity(type); const tupleConstituentNodes = mapToTypeNodes(typeArguments.slice(0, arity), context); @@ -14012,7 +14011,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } else { mapper = createTypeMapper(typeParameters, typeArguments); - members = createInstantiatedSymbolTable(source.declaredProperties, mapper, /*mappingThisOnly*/ typeParameters.length === 1); + const propertiesMapper = isTupleType(type) + ? createTypeMapper(typeParameters, sameMap(typeArguments, (t, i) => addOptionality(t, /*isProperty*/ true, !!(type.target.elementFlags[i] & ElementFlags.Optional)))) + : mapper; + members = createInstantiatedSymbolTable(source.declaredProperties, propertiesMapper, /*mappingThisOnly*/ typeParameters.length === 1); callSignatures = instantiateSignatures(source.declaredCallSignatures, mapper); constructSignatures = instantiateSignatures(source.declaredConstructSignatures, mapper); indexInfos = instantiateIndexInfos(source.declaredIndexInfos, mapper); @@ -17946,7 +17948,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (flags & (ElementFlags.Optional | ElementFlags.Rest)) { lastOptionalOrRestIndex = expandedFlags.length; } - expandedTypes.push(flags & ElementFlags.Optional ? addOptionality(type, /*isProperty*/ true) : type); + expandedTypes.push(flags & ElementFlags.Optional && !exactOptionalPropertyTypes ? addOptionality(type, /*isProperty*/ true) : type); expandedFlags.push(flags); expandedDeclarations.push(declaration); } @@ -17985,7 +17987,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function getTypeFromOptionalTypeNode(node: OptionalTypeNode): Type { - return addOptionality(getTypeFromTypeNode(node.type), /*isProperty*/ true); + const type = getTypeFromTypeNode(node.type); + return exactOptionalPropertyTypes ? type : addOptionality(type, /*isProperty*/ true); } function getTypeId(type: Type): TypeId { @@ -20363,8 +20366,20 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function getTypeFromNamedTupleTypeNode(node: NamedTupleMember): Type { const links = getNodeLinks(node); - return links.resolvedType || (links.resolvedType = node.dotDotDotToken ? getTypeFromRestTypeNode(node) : - addOptionality(getTypeFromTypeNode(node.type), /*isProperty*/ true, !!node.questionToken)); + if (links.resolvedType) { + return links.resolvedType; + } + let type: Type; + if (node.dotDotDotToken) { + type = getTypeFromRestTypeNode(node); + } + else { + type = getTypeFromTypeNode(node.type); + if (!exactOptionalPropertyTypes) { + type = addOptionality(type, /*isProperty*/ true, !!node.questionToken); + } + } + return links.resolvedType = type; } function getTypeFromTypeNode(node: TypeNode): Type { @@ -24438,11 +24453,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } - const sourceType = removeMissingType(sourceTypeArguments[sourcePosition], !!(sourceFlags & targetFlags & ElementFlags.Optional)); + const sourceType = sourceTypeArguments[sourcePosition]; const targetType = targetTypeArguments[targetPosition]; + const targetCheckType = sourceFlags & ElementFlags.Variadic && targetFlags & ElementFlags.Rest ? createArrayType(targetType) : targetType; - const targetCheckType = sourceFlags & ElementFlags.Variadic && targetFlags & ElementFlags.Rest ? createArrayType(targetType) : - removeMissingType(targetType, !!(targetFlags & ElementFlags.Optional)); const related = isRelatedTo(sourceType, targetCheckType, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); if (!related) { if (reportErrors && (targetArity > 1 || sourceArity > 1)) { @@ -32434,7 +32448,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // If index is before any spread element and within the fixed part of the contextual tuple type, return // the type of the contextual tuple element. if ((firstSpreadIndex === undefined || index < firstSpreadIndex) && index < t.target.fixedLength) { - return removeMissingType(getTypeArguments(t)[index], !!(t.target.elementFlags[index] && ElementFlags.Optional)); + return getTypeArguments(t)[index]; } // When the length is known and the index is after all spread elements we compute the offset from the element // to the end and the number of ending fixed elements in the contextual tuple type. @@ -33238,7 +33252,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const contextualType = getApparentTypeOfContextualType(node, /*contextFlags*/ undefined); const inTupleContext = isSpreadIntoCallOrNew(node) || !!contextualType && someType(contextualType, t => isTupleLikeType(t) || isGenericMappedType(t) && !t.nameType && !!getHomomorphicTypeVariable(t.target as MappedType || t)); - let hasOmittedExpression = false; for (let i = 0; i < elementCount; i++) { const e = elements[i]; if (e.kind === SyntaxKind.SpreadElement) { @@ -33275,14 +33288,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } else if (exactOptionalPropertyTypes && e.kind === SyntaxKind.OmittedExpression) { - hasOmittedExpression = true; - elementTypes.push(undefinedOrMissingType); - elementFlags.push(ElementFlags.Optional); + elementTypes.push(undefinedType); + elementFlags.push(ElementFlags.Required); } else { const type = checkExpressionForMutableLocation(e, checkMode, forceTuple); - elementTypes.push(addOptionality(type, /*isProperty*/ true, hasOmittedExpression)); - elementFlags.push(hasOmittedExpression ? ElementFlags.Optional : ElementFlags.Required); + elementTypes.push(type); + elementFlags.push(ElementFlags.Required); if (inTupleContext && checkMode && checkMode & CheckMode.Inferential && !(checkMode & CheckMode.SkipContextSensitive) && isContextSensitive(e)) { const inferenceContext = getInferenceContext(node); Debug.assert(inferenceContext); // In CheckMode.Inferential we should always have an inference context diff --git a/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=es5).errors.txt b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=es5).errors.txt new file mode 100644 index 0000000000000..0bd718f342d0f --- /dev/null +++ b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=es5).errors.txt @@ -0,0 +1,45 @@ +forOfOptionalTupleMember.ts(10,3): error TS18048: 'item' is possibly 'undefined'. +forOfOptionalTupleMember.ts(16,3): error TS18048: 'item' is possibly 'undefined'. +forOfOptionalTupleMember.ts(21,5): error TS18048: 'num' is possibly 'undefined'. +forOfOptionalTupleMember.ts(27,5): error TS18048: 'num' is possibly 'undefined'. + + +==== forOfOptionalTupleMember.ts (4 errors) ==== + // repro from https://github.com/microsoft/TypeScript/issues/54302 + + type Item = { + value: string; + }; + + type Foo = [Item?]; + declare const foo: Foo; + for (let item of foo) { + item.value; + ~~~~ +!!! error TS18048: 'item' is possibly 'undefined'. + } + + type Foo2 = [item?: Item]; + declare const foo2: Foo2; + for (let item of foo2) { + item.value; + ~~~~ +!!! error TS18048: 'item' is possibly 'undefined'. + } + + function fn1(t: [number, number?, number?]) { + for (let num of t) { + num.toString() + ~~~ +!!! error TS18048: 'num' is possibly 'undefined'. + } + } + + function fn2(t: [a: number, b?: number, c?: number]) { + for (let num of t) { + num.toString() + ~~~ +!!! error TS18048: 'num' is possibly 'undefined'. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=es5).symbols b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=es5).symbols new file mode 100644 index 0000000000000..9c9a3b4bb277a --- /dev/null +++ b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=es5).symbols @@ -0,0 +1,79 @@ +//// [tests/cases/compiler/forOfOptionalTupleMember.ts] //// + +=== forOfOptionalTupleMember.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54302 + +type Item = { +>Item : Symbol(Item, Decl(forOfOptionalTupleMember.ts, 0, 0)) + + value: string; +>value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) + +}; + +type Foo = [Item?]; +>Foo : Symbol(Foo, Decl(forOfOptionalTupleMember.ts, 4, 2)) +>Item : Symbol(Item, Decl(forOfOptionalTupleMember.ts, 0, 0)) + +declare const foo: Foo; +>foo : Symbol(foo, Decl(forOfOptionalTupleMember.ts, 7, 13)) +>Foo : Symbol(Foo, Decl(forOfOptionalTupleMember.ts, 4, 2)) + +for (let item of foo) { +>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 8, 8)) +>foo : Symbol(foo, Decl(forOfOptionalTupleMember.ts, 7, 13)) + + item.value; +>item.value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) +>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 8, 8)) +>value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) +} + +type Foo2 = [item?: Item]; +>Foo2 : Symbol(Foo2, Decl(forOfOptionalTupleMember.ts, 10, 1)) +>Item : Symbol(Item, Decl(forOfOptionalTupleMember.ts, 0, 0)) + +declare const foo2: Foo2; +>foo2 : Symbol(foo2, Decl(forOfOptionalTupleMember.ts, 13, 13)) +>Foo2 : Symbol(Foo2, Decl(forOfOptionalTupleMember.ts, 10, 1)) + +for (let item of foo2) { +>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 14, 8)) +>foo2 : Symbol(foo2, Decl(forOfOptionalTupleMember.ts, 13, 13)) + + item.value; +>item.value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) +>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 14, 8)) +>value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) +} + +function fn1(t: [number, number?, number?]) { +>fn1 : Symbol(fn1, Decl(forOfOptionalTupleMember.ts, 16, 1)) +>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 18, 13)) + + for (let num of t) { +>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 19, 10)) +>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 18, 13)) + + num.toString() +>num.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) +>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 19, 10)) +>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) + } +} + +function fn2(t: [a: number, b?: number, c?: number]) { +>fn2 : Symbol(fn2, Decl(forOfOptionalTupleMember.ts, 22, 1)) +>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 24, 13)) + + for (let num of t) { +>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 25, 10)) +>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 24, 13)) + + num.toString() +>num.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) +>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 25, 10)) +>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) + } +} + diff --git a/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=es5).types b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=es5).types new file mode 100644 index 0000000000000..840139c5b85b4 --- /dev/null +++ b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=es5).types @@ -0,0 +1,109 @@ +//// [tests/cases/compiler/forOfOptionalTupleMember.ts] //// + +=== forOfOptionalTupleMember.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54302 + +type Item = { +>Item : Item +> : ^^^^ + + value: string; +>value : string +> : ^^^^^^ + +}; + +type Foo = [Item?]; +>Foo : Foo +> : ^^^ + +declare const foo: Foo; +>foo : Foo +> : ^^^ + +for (let item of foo) { +>item : Item | undefined +> : ^^^^^^^^^^^^^^^^ +>foo : Foo +> : ^^^ + + item.value; +>item.value : string +> : ^^^^^^ +>item : Item | undefined +> : ^^^^^^^^^^^^^^^^ +>value : string +> : ^^^^^^ +} + +type Foo2 = [item?: Item]; +>Foo2 : Foo2 +> : ^^^^ + +declare const foo2: Foo2; +>foo2 : Foo2 +> : ^^^^ + +for (let item of foo2) { +>item : Item | undefined +> : ^^^^^^^^^^^^^^^^ +>foo2 : Foo2 +> : ^^^^ + + item.value; +>item.value : string +> : ^^^^^^ +>item : Item | undefined +> : ^^^^^^^^^^^^^^^^ +>value : string +> : ^^^^^^ +} + +function fn1(t: [number, number?, number?]) { +>fn1 : (t: [number, number?, number?]) => void +> : ^ ^^ ^^^^^^^^^ +>t : [number, (number | undefined)?, (number | undefined)?] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + for (let num of t) { +>num : number | undefined +> : ^^^^^^^^^^^^^^^^^^ +>t : [number, (number | undefined)?, (number | undefined)?] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + num.toString() +>num.toString() : string +> : ^^^^^^ +>num.toString : (radix?: number) => string +> : ^ ^^^ ^^^^^ +>num : number | undefined +> : ^^^^^^^^^^^^^^^^^^ +>toString : (radix?: number) => string +> : ^ ^^^ ^^^^^ + } +} + +function fn2(t: [a: number, b?: number, c?: number]) { +>fn2 : (t: [a: number, b?: number, c?: number]) => void +> : ^ ^^ ^^^^^^^^^ +>t : [a: number, b?: number | undefined, c?: number | undefined] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + for (let num of t) { +>num : number | undefined +> : ^^^^^^^^^^^^^^^^^^ +>t : [a: number, b?: number | undefined, c?: number | undefined] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + num.toString() +>num.toString() : string +> : ^^^^^^ +>num.toString : (radix?: number) => string +> : ^ ^^^ ^^^^^ +>num : number | undefined +> : ^^^^^^^^^^^^^^^^^^ +>toString : (radix?: number) => string +> : ^ ^^^ ^^^^^ + } +} + diff --git a/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=esnext).errors.txt b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=esnext).errors.txt new file mode 100644 index 0000000000000..0bd718f342d0f --- /dev/null +++ b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=esnext).errors.txt @@ -0,0 +1,45 @@ +forOfOptionalTupleMember.ts(10,3): error TS18048: 'item' is possibly 'undefined'. +forOfOptionalTupleMember.ts(16,3): error TS18048: 'item' is possibly 'undefined'. +forOfOptionalTupleMember.ts(21,5): error TS18048: 'num' is possibly 'undefined'. +forOfOptionalTupleMember.ts(27,5): error TS18048: 'num' is possibly 'undefined'. + + +==== forOfOptionalTupleMember.ts (4 errors) ==== + // repro from https://github.com/microsoft/TypeScript/issues/54302 + + type Item = { + value: string; + }; + + type Foo = [Item?]; + declare const foo: Foo; + for (let item of foo) { + item.value; + ~~~~ +!!! error TS18048: 'item' is possibly 'undefined'. + } + + type Foo2 = [item?: Item]; + declare const foo2: Foo2; + for (let item of foo2) { + item.value; + ~~~~ +!!! error TS18048: 'item' is possibly 'undefined'. + } + + function fn1(t: [number, number?, number?]) { + for (let num of t) { + num.toString() + ~~~ +!!! error TS18048: 'num' is possibly 'undefined'. + } + } + + function fn2(t: [a: number, b?: number, c?: number]) { + for (let num of t) { + num.toString() + ~~~ +!!! error TS18048: 'num' is possibly 'undefined'. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=esnext).symbols b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=esnext).symbols new file mode 100644 index 0000000000000..9c9a3b4bb277a --- /dev/null +++ b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=esnext).symbols @@ -0,0 +1,79 @@ +//// [tests/cases/compiler/forOfOptionalTupleMember.ts] //// + +=== forOfOptionalTupleMember.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54302 + +type Item = { +>Item : Symbol(Item, Decl(forOfOptionalTupleMember.ts, 0, 0)) + + value: string; +>value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) + +}; + +type Foo = [Item?]; +>Foo : Symbol(Foo, Decl(forOfOptionalTupleMember.ts, 4, 2)) +>Item : Symbol(Item, Decl(forOfOptionalTupleMember.ts, 0, 0)) + +declare const foo: Foo; +>foo : Symbol(foo, Decl(forOfOptionalTupleMember.ts, 7, 13)) +>Foo : Symbol(Foo, Decl(forOfOptionalTupleMember.ts, 4, 2)) + +for (let item of foo) { +>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 8, 8)) +>foo : Symbol(foo, Decl(forOfOptionalTupleMember.ts, 7, 13)) + + item.value; +>item.value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) +>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 8, 8)) +>value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) +} + +type Foo2 = [item?: Item]; +>Foo2 : Symbol(Foo2, Decl(forOfOptionalTupleMember.ts, 10, 1)) +>Item : Symbol(Item, Decl(forOfOptionalTupleMember.ts, 0, 0)) + +declare const foo2: Foo2; +>foo2 : Symbol(foo2, Decl(forOfOptionalTupleMember.ts, 13, 13)) +>Foo2 : Symbol(Foo2, Decl(forOfOptionalTupleMember.ts, 10, 1)) + +for (let item of foo2) { +>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 14, 8)) +>foo2 : Symbol(foo2, Decl(forOfOptionalTupleMember.ts, 13, 13)) + + item.value; +>item.value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) +>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 14, 8)) +>value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) +} + +function fn1(t: [number, number?, number?]) { +>fn1 : Symbol(fn1, Decl(forOfOptionalTupleMember.ts, 16, 1)) +>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 18, 13)) + + for (let num of t) { +>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 19, 10)) +>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 18, 13)) + + num.toString() +>num.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) +>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 19, 10)) +>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) + } +} + +function fn2(t: [a: number, b?: number, c?: number]) { +>fn2 : Symbol(fn2, Decl(forOfOptionalTupleMember.ts, 22, 1)) +>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 24, 13)) + + for (let num of t) { +>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 25, 10)) +>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 24, 13)) + + num.toString() +>num.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) +>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 25, 10)) +>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) + } +} + diff --git a/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=esnext).types b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=esnext).types new file mode 100644 index 0000000000000..840139c5b85b4 --- /dev/null +++ b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=esnext).types @@ -0,0 +1,109 @@ +//// [tests/cases/compiler/forOfOptionalTupleMember.ts] //// + +=== forOfOptionalTupleMember.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54302 + +type Item = { +>Item : Item +> : ^^^^ + + value: string; +>value : string +> : ^^^^^^ + +}; + +type Foo = [Item?]; +>Foo : Foo +> : ^^^ + +declare const foo: Foo; +>foo : Foo +> : ^^^ + +for (let item of foo) { +>item : Item | undefined +> : ^^^^^^^^^^^^^^^^ +>foo : Foo +> : ^^^ + + item.value; +>item.value : string +> : ^^^^^^ +>item : Item | undefined +> : ^^^^^^^^^^^^^^^^ +>value : string +> : ^^^^^^ +} + +type Foo2 = [item?: Item]; +>Foo2 : Foo2 +> : ^^^^ + +declare const foo2: Foo2; +>foo2 : Foo2 +> : ^^^^ + +for (let item of foo2) { +>item : Item | undefined +> : ^^^^^^^^^^^^^^^^ +>foo2 : Foo2 +> : ^^^^ + + item.value; +>item.value : string +> : ^^^^^^ +>item : Item | undefined +> : ^^^^^^^^^^^^^^^^ +>value : string +> : ^^^^^^ +} + +function fn1(t: [number, number?, number?]) { +>fn1 : (t: [number, number?, number?]) => void +> : ^ ^^ ^^^^^^^^^ +>t : [number, (number | undefined)?, (number | undefined)?] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + for (let num of t) { +>num : number | undefined +> : ^^^^^^^^^^^^^^^^^^ +>t : [number, (number | undefined)?, (number | undefined)?] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + num.toString() +>num.toString() : string +> : ^^^^^^ +>num.toString : (radix?: number) => string +> : ^ ^^^ ^^^^^ +>num : number | undefined +> : ^^^^^^^^^^^^^^^^^^ +>toString : (radix?: number) => string +> : ^ ^^^ ^^^^^ + } +} + +function fn2(t: [a: number, b?: number, c?: number]) { +>fn2 : (t: [a: number, b?: number, c?: number]) => void +> : ^ ^^ ^^^^^^^^^ +>t : [a: number, b?: number | undefined, c?: number | undefined] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + for (let num of t) { +>num : number | undefined +> : ^^^^^^^^^^^^^^^^^^ +>t : [a: number, b?: number | undefined, c?: number | undefined] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + num.toString() +>num.toString() : string +> : ^^^^^^ +>num.toString : (radix?: number) => string +> : ^ ^^^ ^^^^^ +>num : number | undefined +> : ^^^^^^^^^^^^^^^^^^ +>toString : (radix?: number) => string +> : ^ ^^^ ^^^^^ + } +} + diff --git a/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=true,target=es5).symbols b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=true,target=es5).symbols new file mode 100644 index 0000000000000..9c9a3b4bb277a --- /dev/null +++ b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=true,target=es5).symbols @@ -0,0 +1,79 @@ +//// [tests/cases/compiler/forOfOptionalTupleMember.ts] //// + +=== forOfOptionalTupleMember.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54302 + +type Item = { +>Item : Symbol(Item, Decl(forOfOptionalTupleMember.ts, 0, 0)) + + value: string; +>value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) + +}; + +type Foo = [Item?]; +>Foo : Symbol(Foo, Decl(forOfOptionalTupleMember.ts, 4, 2)) +>Item : Symbol(Item, Decl(forOfOptionalTupleMember.ts, 0, 0)) + +declare const foo: Foo; +>foo : Symbol(foo, Decl(forOfOptionalTupleMember.ts, 7, 13)) +>Foo : Symbol(Foo, Decl(forOfOptionalTupleMember.ts, 4, 2)) + +for (let item of foo) { +>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 8, 8)) +>foo : Symbol(foo, Decl(forOfOptionalTupleMember.ts, 7, 13)) + + item.value; +>item.value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) +>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 8, 8)) +>value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) +} + +type Foo2 = [item?: Item]; +>Foo2 : Symbol(Foo2, Decl(forOfOptionalTupleMember.ts, 10, 1)) +>Item : Symbol(Item, Decl(forOfOptionalTupleMember.ts, 0, 0)) + +declare const foo2: Foo2; +>foo2 : Symbol(foo2, Decl(forOfOptionalTupleMember.ts, 13, 13)) +>Foo2 : Symbol(Foo2, Decl(forOfOptionalTupleMember.ts, 10, 1)) + +for (let item of foo2) { +>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 14, 8)) +>foo2 : Symbol(foo2, Decl(forOfOptionalTupleMember.ts, 13, 13)) + + item.value; +>item.value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) +>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 14, 8)) +>value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) +} + +function fn1(t: [number, number?, number?]) { +>fn1 : Symbol(fn1, Decl(forOfOptionalTupleMember.ts, 16, 1)) +>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 18, 13)) + + for (let num of t) { +>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 19, 10)) +>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 18, 13)) + + num.toString() +>num.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) +>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 19, 10)) +>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) + } +} + +function fn2(t: [a: number, b?: number, c?: number]) { +>fn2 : Symbol(fn2, Decl(forOfOptionalTupleMember.ts, 22, 1)) +>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 24, 13)) + + for (let num of t) { +>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 25, 10)) +>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 24, 13)) + + num.toString() +>num.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) +>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 25, 10)) +>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) + } +} + diff --git a/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=true,target=es5).types b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=true,target=es5).types new file mode 100644 index 0000000000000..d148305204887 --- /dev/null +++ b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=true,target=es5).types @@ -0,0 +1,109 @@ +//// [tests/cases/compiler/forOfOptionalTupleMember.ts] //// + +=== forOfOptionalTupleMember.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54302 + +type Item = { +>Item : Item +> : ^^^^ + + value: string; +>value : string +> : ^^^^^^ + +}; + +type Foo = [Item?]; +>Foo : Foo +> : ^^^ + +declare const foo: Foo; +>foo : Foo +> : ^^^ + +for (let item of foo) { +>item : Item +> : ^^^^ +>foo : Foo +> : ^^^ + + item.value; +>item.value : string +> : ^^^^^^ +>item : Item +> : ^^^^ +>value : string +> : ^^^^^^ +} + +type Foo2 = [item?: Item]; +>Foo2 : Foo2 +> : ^^^^ + +declare const foo2: Foo2; +>foo2 : Foo2 +> : ^^^^ + +for (let item of foo2) { +>item : Item +> : ^^^^ +>foo2 : Foo2 +> : ^^^^ + + item.value; +>item.value : string +> : ^^^^^^ +>item : Item +> : ^^^^ +>value : string +> : ^^^^^^ +} + +function fn1(t: [number, number?, number?]) { +>fn1 : (t: [number, number?, number?]) => void +> : ^ ^^ ^^^^^^^^^ +>t : [number, number?, number?] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^ + + for (let num of t) { +>num : number +> : ^^^^^^ +>t : [number, number?, number?] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^ + + num.toString() +>num.toString() : string +> : ^^^^^^ +>num.toString : (radix?: number) => string +> : ^ ^^^ ^^^^^ +>num : number +> : ^^^^^^ +>toString : (radix?: number) => string +> : ^ ^^^ ^^^^^ + } +} + +function fn2(t: [a: number, b?: number, c?: number]) { +>fn2 : (t: [a: number, b?: number, c?: number]) => void +> : ^ ^^ ^^^^^^^^^ +>t : [a: number, b?: number, c?: number] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + for (let num of t) { +>num : number +> : ^^^^^^ +>t : [a: number, b?: number, c?: number] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + num.toString() +>num.toString() : string +> : ^^^^^^ +>num.toString : (radix?: number) => string +> : ^ ^^^ ^^^^^ +>num : number +> : ^^^^^^ +>toString : (radix?: number) => string +> : ^ ^^^ ^^^^^ + } +} + diff --git a/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=true,target=esnext).symbols b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=true,target=esnext).symbols new file mode 100644 index 0000000000000..9c9a3b4bb277a --- /dev/null +++ b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=true,target=esnext).symbols @@ -0,0 +1,79 @@ +//// [tests/cases/compiler/forOfOptionalTupleMember.ts] //// + +=== forOfOptionalTupleMember.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54302 + +type Item = { +>Item : Symbol(Item, Decl(forOfOptionalTupleMember.ts, 0, 0)) + + value: string; +>value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) + +}; + +type Foo = [Item?]; +>Foo : Symbol(Foo, Decl(forOfOptionalTupleMember.ts, 4, 2)) +>Item : Symbol(Item, Decl(forOfOptionalTupleMember.ts, 0, 0)) + +declare const foo: Foo; +>foo : Symbol(foo, Decl(forOfOptionalTupleMember.ts, 7, 13)) +>Foo : Symbol(Foo, Decl(forOfOptionalTupleMember.ts, 4, 2)) + +for (let item of foo) { +>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 8, 8)) +>foo : Symbol(foo, Decl(forOfOptionalTupleMember.ts, 7, 13)) + + item.value; +>item.value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) +>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 8, 8)) +>value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) +} + +type Foo2 = [item?: Item]; +>Foo2 : Symbol(Foo2, Decl(forOfOptionalTupleMember.ts, 10, 1)) +>Item : Symbol(Item, Decl(forOfOptionalTupleMember.ts, 0, 0)) + +declare const foo2: Foo2; +>foo2 : Symbol(foo2, Decl(forOfOptionalTupleMember.ts, 13, 13)) +>Foo2 : Symbol(Foo2, Decl(forOfOptionalTupleMember.ts, 10, 1)) + +for (let item of foo2) { +>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 14, 8)) +>foo2 : Symbol(foo2, Decl(forOfOptionalTupleMember.ts, 13, 13)) + + item.value; +>item.value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) +>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 14, 8)) +>value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13)) +} + +function fn1(t: [number, number?, number?]) { +>fn1 : Symbol(fn1, Decl(forOfOptionalTupleMember.ts, 16, 1)) +>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 18, 13)) + + for (let num of t) { +>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 19, 10)) +>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 18, 13)) + + num.toString() +>num.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) +>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 19, 10)) +>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) + } +} + +function fn2(t: [a: number, b?: number, c?: number]) { +>fn2 : Symbol(fn2, Decl(forOfOptionalTupleMember.ts, 22, 1)) +>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 24, 13)) + + for (let num of t) { +>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 25, 10)) +>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 24, 13)) + + num.toString() +>num.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) +>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 25, 10)) +>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) + } +} + diff --git a/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=true,target=esnext).types b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=true,target=esnext).types new file mode 100644 index 0000000000000..d148305204887 --- /dev/null +++ b/tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=true,target=esnext).types @@ -0,0 +1,109 @@ +//// [tests/cases/compiler/forOfOptionalTupleMember.ts] //// + +=== forOfOptionalTupleMember.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54302 + +type Item = { +>Item : Item +> : ^^^^ + + value: string; +>value : string +> : ^^^^^^ + +}; + +type Foo = [Item?]; +>Foo : Foo +> : ^^^ + +declare const foo: Foo; +>foo : Foo +> : ^^^ + +for (let item of foo) { +>item : Item +> : ^^^^ +>foo : Foo +> : ^^^ + + item.value; +>item.value : string +> : ^^^^^^ +>item : Item +> : ^^^^ +>value : string +> : ^^^^^^ +} + +type Foo2 = [item?: Item]; +>Foo2 : Foo2 +> : ^^^^ + +declare const foo2: Foo2; +>foo2 : Foo2 +> : ^^^^ + +for (let item of foo2) { +>item : Item +> : ^^^^ +>foo2 : Foo2 +> : ^^^^ + + item.value; +>item.value : string +> : ^^^^^^ +>item : Item +> : ^^^^ +>value : string +> : ^^^^^^ +} + +function fn1(t: [number, number?, number?]) { +>fn1 : (t: [number, number?, number?]) => void +> : ^ ^^ ^^^^^^^^^ +>t : [number, number?, number?] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^ + + for (let num of t) { +>num : number +> : ^^^^^^ +>t : [number, number?, number?] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^ + + num.toString() +>num.toString() : string +> : ^^^^^^ +>num.toString : (radix?: number) => string +> : ^ ^^^ ^^^^^ +>num : number +> : ^^^^^^ +>toString : (radix?: number) => string +> : ^ ^^^ ^^^^^ + } +} + +function fn2(t: [a: number, b?: number, c?: number]) { +>fn2 : (t: [a: number, b?: number, c?: number]) => void +> : ^ ^^ ^^^^^^^^^ +>t : [a: number, b?: number, c?: number] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + for (let num of t) { +>num : number +> : ^^^^^^ +>t : [a: number, b?: number, c?: number] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + num.toString() +>num.toString() : string +> : ^^^^^^ +>num.toString : (radix?: number) => string +> : ^ ^^^ ^^^^^ +>num : number +> : ^^^^^^ +>toString : (radix?: number) => string +> : ^ ^^^ ^^^^^ + } +} + diff --git a/tests/baselines/reference/strictOptionalProperties1.errors.txt b/tests/baselines/reference/strictOptionalProperties1.errors.txt index 237279463390c..6e4270ad162b8 100644 --- a/tests/baselines/reference/strictOptionalProperties1.errors.txt +++ b/tests/baselines/reference/strictOptionalProperties1.errors.txt @@ -7,10 +7,17 @@ strictOptionalProperties1.ts(53,5): error TS2412: Type 'undefined' is not assign strictOptionalProperties1.ts(60,5): error TS2322: Type 'undefined' is not assignable to type 'string'. strictOptionalProperties1.ts(64,5): error TS2322: Type '[number, string?, string?]' is not assignable to type '[number, string?]'. Target allows only 2 element(s) but source may have more. -strictOptionalProperties1.ts(73,5): error TS2322: Type '[number, never?, never?, never?]' is not assignable to type '[number, string?, boolean?]'. - Target allows only 3 element(s) but source may have more. -strictOptionalProperties1.ts(74,5): error TS2322: Type '[never?, never?, true?]' is not assignable to type '[number, string?, boolean?]'. - Source provides no match for required element at position 0 in target. +strictOptionalProperties1.ts(71,5): error TS2322: Type '[number, undefined]' is not assignable to type '[number, string?, boolean?]'. + Type at position 1 in source is not compatible with type at position 1 in target. + Type 'undefined' is not assignable to type 'string'. +strictOptionalProperties1.ts(72,5): error TS2322: Type '[number, undefined, undefined]' is not assignable to type '[number, string?, boolean?]'. + Type at position 1 in source is not compatible with type at position 1 in target. + Type 'undefined' is not assignable to type 'string'. +strictOptionalProperties1.ts(73,5): error TS2322: Type '[number, undefined, undefined, undefined]' is not assignable to type '[number, string?, boolean?]'. + Source has 4 element(s) but target allows only 3. +strictOptionalProperties1.ts(74,5): error TS2322: Type '[undefined, undefined, true]' is not assignable to type '[number, string?, boolean?]'. + Type at position 0 in source is not compatible with type at position 0 in target. + Type 'undefined' is not assignable to type 'number'. strictOptionalProperties1.ts(75,5): error TS2322: Type '[number, undefined, true]' is not assignable to type '[number, string?, boolean?]'. Type at position 1 in source is not compatible with type at position 1 in target. Type 'undefined' is not assignable to type 'string'. @@ -47,7 +54,7 @@ strictOptionalProperties1.ts(211,1): error TS2322: Type 'string | boolean | unde Type 'undefined' is not assignable to type '{ [x: string]: string | number; }'. -==== strictOptionalProperties1.ts (23 errors) ==== +==== strictOptionalProperties1.ts (25 errors) ==== function f1(obj: { a?: string, b?: string | undefined }) { let a = obj.a; // string | undefined let b = obj.b; // string | undefined @@ -135,15 +142,24 @@ strictOptionalProperties1.ts(211,1): error TS2322: Type 'string | boolean | unde t = [42, 'abc']; t = [42, 'abc', true]; t = [42, ,]; + ~ +!!! error TS2322: Type '[number, undefined]' is not assignable to type '[number, string?, boolean?]'. +!!! error TS2322: Type at position 1 in source is not compatible with type at position 1 in target. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. t = [42, , ,]; + ~ +!!! error TS2322: Type '[number, undefined, undefined]' is not assignable to type '[number, string?, boolean?]'. +!!! error TS2322: Type at position 1 in source is not compatible with type at position 1 in target. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. t = [42, , , ,]; // Error ~ -!!! error TS2322: Type '[number, never?, never?, never?]' is not assignable to type '[number, string?, boolean?]'. -!!! error TS2322: Target allows only 3 element(s) but source may have more. +!!! error TS2322: Type '[number, undefined, undefined, undefined]' is not assignable to type '[number, string?, boolean?]'. +!!! error TS2322: Source has 4 element(s) but target allows only 3. t = [, , true]; // Error ~ -!!! error TS2322: Type '[never?, never?, true?]' is not assignable to type '[number, string?, boolean?]'. -!!! error TS2322: Source provides no match for required element at position 0 in target. +!!! error TS2322: Type '[undefined, undefined, true]' is not assignable to type '[number, string?, boolean?]'. +!!! error TS2322: Type at position 0 in source is not compatible with type at position 0 in target. +!!! error TS2322: Type 'undefined' is not assignable to type 'number'. t = [42, undefined, true]; // Error ~ !!! error TS2322: Type '[number, undefined, true]' is not assignable to type '[number, string?, boolean?]'. diff --git a/tests/baselines/reference/strictOptionalProperties1.types b/tests/baselines/reference/strictOptionalProperties1.types index 6407140da10cf..cf6c2793b6c16 100644 --- a/tests/baselines/reference/strictOptionalProperties1.types +++ b/tests/baselines/reference/strictOptionalProperties1.types @@ -548,24 +548,24 @@ function f5(t: [number, string?, boolean?]) { > : ^^^^ t = [42, ,]; ->t = [42, ,] : [number, never?] -> : ^^^^^^^^^^^^^^^^ +>t = [42, ,] : [number, undefined] +> : ^^^^^^^^^^^^^^^^^^^ >t : [number, string?, boolean?] > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->[42, ,] : [number, never?] -> : ^^^^^^^^^^^^^^^^ +>[42, ,] : [number, undefined] +> : ^^^^^^^^^^^^^^^^^^^ >42 : 42 > : ^^ > : undefined > : ^^^^^^^^^ t = [42, , ,]; ->t = [42, , ,] : [number, never?, never?] -> : ^^^^^^^^^^^^^^^^^^^^^^^^ +>t = [42, , ,] : [number, undefined, undefined] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >t : [number, string?, boolean?] > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->[42, , ,] : [number, never?, never?] -> : ^^^^^^^^^^^^^^^^^^^^^^^^ +>[42, , ,] : [number, undefined, undefined] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >42 : 42 > : ^^ > : undefined @@ -574,12 +574,12 @@ function f5(t: [number, string?, boolean?]) { > : ^^^^^^^^^ t = [42, , , ,]; // Error ->t = [42, , , ,] : [number, never?, never?, never?] -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>t = [42, , , ,] : [number, undefined, undefined, undefined] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >t : [number, string?, boolean?] > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->[42, , , ,] : [number, never?, never?, never?] -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>[42, , , ,] : [number, undefined, undefined, undefined] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >42 : 42 > : ^^ > : undefined @@ -590,12 +590,12 @@ function f5(t: [number, string?, boolean?]) { > : ^^^^^^^^^ t = [, , true]; // Error ->t = [, , true] : [never?, never?, true?] -> : ^^^^^^^^^^^^^^^^^^^^^^^ +>t = [, , true] : [undefined, undefined, true] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >t : [number, string?, boolean?] > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->[, , true] : [never?, never?, true?] -> : ^^^^^^^^^^^^^^^^^^^^^^^ +>[, , true] : [undefined, undefined, true] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > : undefined > : ^^^^^^^^^ > : undefined @@ -635,12 +635,12 @@ function f6() { > : ^ const t2 = [1, 2, ,] as const; ->t2 : readonly [1, 2, never?] -> : ^^^^^^^^^^^^^^^^^^^^^^^ ->[1, 2, ,] as const : readonly [1, 2, never?] -> : ^^^^^^^^^^^^^^^^^^^^^^^ ->[1, 2, ,] : readonly [1, 2, never?] -> : ^^^^^^^^^^^^^^^^^^^^^^^ +>t2 : readonly [1, 2, undefined] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^ +>[1, 2, ,] as const : readonly [1, 2, undefined] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^ +>[1, 2, ,] : readonly [1, 2, undefined] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^ >1 : 1 > : ^ >2 : 2 @@ -649,12 +649,12 @@ function f6() { > : ^^^^^^^^^ const t3 = [1, 2, , ,] as const; ->t3 : readonly [1, 2, never?, never?] -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->[1, 2, , ,] as const : readonly [1, 2, never?, never?] -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->[1, 2, , ,] : readonly [1, 2, never?, never?] -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>t3 : readonly [1, 2, undefined, undefined] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>[1, 2, , ,] as const : readonly [1, 2, undefined, undefined] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>[1, 2, , ,] : readonly [1, 2, undefined, undefined] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >1 : 1 > : ^ >2 : 2 @@ -665,12 +665,12 @@ function f6() { > : ^^^^^^^^^ const t4 = [1, , 2] as const; ->t4 : readonly [1, never?, 2?] -> : ^^^^^^^^^^^^^^^^^^^^^^^^ ->[1, , 2] as const : readonly [1, never?, 2?] -> : ^^^^^^^^^^^^^^^^^^^^^^^^ ->[1, , 2] : readonly [1, never?, 2?] -> : ^^^^^^^^^^^^^^^^^^^^^^^^ +>t4 : readonly [1, undefined, 2] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^ +>[1, , 2] as const : readonly [1, undefined, 2] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^ +>[1, , 2] : readonly [1, undefined, 2] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^ >1 : 1 > : ^ > : undefined @@ -679,12 +679,12 @@ function f6() { > : ^ const t5 = [1, , , 2] as const; ->t5 : readonly [1, never?, never?, 2?] -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->[1, , , 2] as const : readonly [1, never?, never?, 2?] -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->[1, , , 2] : readonly [1, never?, never?, 2?] -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>t5 : readonly [1, undefined, undefined, 2] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>[1, , , 2] as const : readonly [1, undefined, undefined, 2] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>[1, , , 2] : readonly [1, undefined, undefined, 2] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >1 : 1 > : ^ > : undefined diff --git a/tests/baselines/reference/strictOptionalPropertiesErrors1.errors.txt b/tests/baselines/reference/strictOptionalPropertiesErrors1.errors.txt new file mode 100644 index 0000000000000..bcb6190a82bc5 --- /dev/null +++ b/tests/baselines/reference/strictOptionalPropertiesErrors1.errors.txt @@ -0,0 +1,9 @@ +strictOptionalPropertiesErrors1.ts(2,15): error TS2322: Type 'string' is not assignable to type 'number | boolean'. + + +==== strictOptionalPropertiesErrors1.ts (1 errors) ==== + function test1(arg: [string, (boolean | number)?]) {} + test1(['foo', 'bar']); + ~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number | boolean'. + \ No newline at end of file diff --git a/tests/baselines/reference/strictOptionalPropertiesErrors1.symbols b/tests/baselines/reference/strictOptionalPropertiesErrors1.symbols new file mode 100644 index 0000000000000..4084e7965b7a8 --- /dev/null +++ b/tests/baselines/reference/strictOptionalPropertiesErrors1.symbols @@ -0,0 +1,10 @@ +//// [tests/cases/compiler/strictOptionalPropertiesErrors1.ts] //// + +=== strictOptionalPropertiesErrors1.ts === +function test1(arg: [string, (boolean | number)?]) {} +>test1 : Symbol(test1, Decl(strictOptionalPropertiesErrors1.ts, 0, 0)) +>arg : Symbol(arg, Decl(strictOptionalPropertiesErrors1.ts, 0, 15)) + +test1(['foo', 'bar']); +>test1 : Symbol(test1, Decl(strictOptionalPropertiesErrors1.ts, 0, 0)) + diff --git a/tests/baselines/reference/strictOptionalPropertiesErrors1.types b/tests/baselines/reference/strictOptionalPropertiesErrors1.types new file mode 100644 index 0000000000000..b3f9290e1d22a --- /dev/null +++ b/tests/baselines/reference/strictOptionalPropertiesErrors1.types @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/strictOptionalPropertiesErrors1.ts] //// + +=== strictOptionalPropertiesErrors1.ts === +function test1(arg: [string, (boolean | number)?]) {} +>test1 : (arg: [string, (boolean | number)?]) => void +> : ^ ^^ ^^^^^^^^^ +>arg : [string, (number | boolean)?] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +test1(['foo', 'bar']); +>test1(['foo', 'bar']) : void +> : ^^^^ +>test1 : (arg: [string, (boolean | number)?]) => void +> : ^ ^^ ^^^^^^^^^ +>['foo', 'bar'] : [string, string] +> : ^^^^^^^^^^^^^^^^ +>'foo' : "foo" +> : ^^^^^ +>'bar' : "bar" +> : ^^^^^ + diff --git a/tests/baselines/reference/strictOptionalPropertiesOmittedExpressions1.symbols b/tests/baselines/reference/strictOptionalPropertiesOmittedExpressions1.symbols new file mode 100644 index 0000000000000..de57ea048ca8d --- /dev/null +++ b/tests/baselines/reference/strictOptionalPropertiesOmittedExpressions1.symbols @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/strictOptionalPropertiesOmittedExpressions1.ts] //// + +=== strictOptionalPropertiesOmittedExpressions1.ts === +function test1(arg: [number, undefined, string]) {} +>test1 : Symbol(test1, Decl(strictOptionalPropertiesOmittedExpressions1.ts, 0, 0)) +>arg : Symbol(arg, Decl(strictOptionalPropertiesOmittedExpressions1.ts, 0, 15)) + +test1([10, , "foo"]); // ok +>test1 : Symbol(test1, Decl(strictOptionalPropertiesOmittedExpressions1.ts, 0, 0)) + +const test2 = ["foo", ,] as const; +>test2 : Symbol(test2, Decl(strictOptionalPropertiesOmittedExpressions1.ts, 3, 5)) +>const : Symbol(const) + +const length2 = test2.length; // 2 +>length2 : Symbol(length2, Decl(strictOptionalPropertiesOmittedExpressions1.ts, 4, 5)) +>test2.length : Symbol(length) +>test2 : Symbol(test2, Decl(strictOptionalPropertiesOmittedExpressions1.ts, 3, 5)) +>length : Symbol(length) + diff --git a/tests/baselines/reference/strictOptionalPropertiesOmittedExpressions1.types b/tests/baselines/reference/strictOptionalPropertiesOmittedExpressions1.types new file mode 100644 index 0000000000000..af1493166e9ca --- /dev/null +++ b/tests/baselines/reference/strictOptionalPropertiesOmittedExpressions1.types @@ -0,0 +1,45 @@ +//// [tests/cases/compiler/strictOptionalPropertiesOmittedExpressions1.ts] //// + +=== strictOptionalPropertiesOmittedExpressions1.ts === +function test1(arg: [number, undefined, string]) {} +>test1 : (arg: [number, undefined, string]) => void +> : ^ ^^ ^^^^^^^^^ +>arg : [number, undefined, string] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +test1([10, , "foo"]); // ok +>test1([10, , "foo"]) : void +> : ^^^^ +>test1 : (arg: [number, undefined, string]) => void +> : ^ ^^ ^^^^^^^^^ +>[10, , "foo"] : [number, undefined, string] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>10 : 10 +> : ^^ +> : undefined +> : ^^^^^^^^^ +>"foo" : "foo" +> : ^^^^^ + +const test2 = ["foo", ,] as const; +>test2 : readonly ["foo", undefined] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>["foo", ,] as const : readonly ["foo", undefined] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>["foo", ,] : readonly ["foo", undefined] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"foo" : "foo" +> : ^^^^^ +> : undefined +> : ^^^^^^^^^ + +const length2 = test2.length; // 2 +>length2 : 2 +> : ^ +>test2.length : 2 +> : ^ +>test2 : readonly ["foo", undefined] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>length : 2 +> : ^ + diff --git a/tests/cases/compiler/forOfOptionalTupleMember.ts b/tests/cases/compiler/forOfOptionalTupleMember.ts new file mode 100644 index 0000000000000..72921295ed17a --- /dev/null +++ b/tests/cases/compiler/forOfOptionalTupleMember.ts @@ -0,0 +1,34 @@ +// @strict: true +// @target: es5, esnext +// @exactOptionalPropertyTypes: true, false +// @noEmit: true + +// repro from https://github.com/microsoft/TypeScript/issues/54302 + +type Item = { + value: string; +}; + +type Foo = [Item?]; +declare const foo: Foo; +for (let item of foo) { + item.value; +} + +type Foo2 = [item?: Item]; +declare const foo2: Foo2; +for (let item of foo2) { + item.value; +} + +function fn1(t: [number, number?, number?]) { + for (let num of t) { + num.toString() + } +} + +function fn2(t: [a: number, b?: number, c?: number]) { + for (let num of t) { + num.toString() + } +} diff --git a/tests/cases/compiler/strictOptionalPropertiesErrors1.ts b/tests/cases/compiler/strictOptionalPropertiesErrors1.ts new file mode 100644 index 0000000000000..9ec79a739e2db --- /dev/null +++ b/tests/cases/compiler/strictOptionalPropertiesErrors1.ts @@ -0,0 +1,6 @@ +// @strict: true +// @exactOptionalPropertyTypes: true +// @noEmit: true + +function test1(arg: [string, (boolean | number)?]) {} +test1(['foo', 'bar']); diff --git a/tests/cases/compiler/strictOptionalPropertiesOmittedExpressions1.ts b/tests/cases/compiler/strictOptionalPropertiesOmittedExpressions1.ts new file mode 100644 index 0000000000000..14eab880b981f --- /dev/null +++ b/tests/cases/compiler/strictOptionalPropertiesOmittedExpressions1.ts @@ -0,0 +1,9 @@ +// @strict: true +// @exactOptionalPropertyTypes: true +// @noEmit: true + +function test1(arg: [number, undefined, string]) {} +test1([10, , "foo"]); // ok + +const test2 = ["foo", ,] as const; +const length2 = test2.length; // 2