Merge pull request #19513 from Microsoft/strictObjectLiterals
Improved type inference for object literals
This commit is contained in:
commit
7798f69558
|
@ -260,6 +260,7 @@ namespace ts {
|
|||
const literalTypes = createMap<LiteralType>();
|
||||
const indexedAccessTypes = createMap<IndexedAccessType>();
|
||||
const evolvingArrayTypes: EvolvingArrayType[] = [];
|
||||
const undefinedProperties = createMap<Symbol>() as UnderscoreEscapedMap<Symbol>;
|
||||
|
||||
const unknownSymbol = createSymbol(SymbolFlags.Property, "unknown" as __String);
|
||||
const resolvingSymbol = createSymbol(0, InternalSymbolName.Resolving);
|
||||
|
@ -7984,7 +7985,7 @@ namespace ts {
|
|||
const spread = createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
|
||||
spread.flags |= propagatedFlags;
|
||||
spread.flags |= TypeFlags.FreshLiteral | TypeFlags.ContainsObjectLiteral;
|
||||
(spread as ObjectType).objectFlags |= ObjectFlags.ObjectLiteral;
|
||||
(spread as ObjectType).objectFlags |= (ObjectFlags.ObjectLiteral | ObjectFlags.ContainsSpread);
|
||||
spread.symbol = symbol;
|
||||
return spread;
|
||||
}
|
||||
|
@ -9026,7 +9027,7 @@ namespace ts {
|
|||
|
||||
if (isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return Ternary.True;
|
||||
|
||||
if (getObjectFlags(source) & ObjectFlags.ObjectLiteral && source.flags & TypeFlags.FreshLiteral) {
|
||||
if (isObjectLiteralType(source) && source.flags & TypeFlags.FreshLiteral) {
|
||||
if (hasExcessProperties(<FreshObjectLiteralType>source, target, reportErrors)) {
|
||||
if (reportErrors) {
|
||||
reportRelationError(headMessage, source, target);
|
||||
|
@ -9596,7 +9597,7 @@ namespace ts {
|
|||
if (relation === identityRelation) {
|
||||
return propertiesIdenticalTo(source, target);
|
||||
}
|
||||
const requireOptionalProperties = relation === subtypeRelation && !(getObjectFlags(source) & ObjectFlags.ObjectLiteral);
|
||||
const requireOptionalProperties = relation === subtypeRelation && !isObjectLiteralType(source);
|
||||
const unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties);
|
||||
if (unmatchedProperty) {
|
||||
if (reportErrors) {
|
||||
|
@ -9604,6 +9605,19 @@ namespace ts {
|
|||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
if (isObjectLiteralType(target)) {
|
||||
for (const sourceProp of getPropertiesOfType(source)) {
|
||||
if (!getPropertyOfObjectType(target, sourceProp.escapedName)) {
|
||||
const sourceType = getTypeOfSymbol(sourceProp);
|
||||
if (!(sourceType === undefinedType || sourceType === undefinedWideningType)) {
|
||||
if (reportErrors) {
|
||||
reportError(Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(sourceProp), typeToString(target));
|
||||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let result = Ternary.True;
|
||||
const properties = getPropertiesOfObjectType(target);
|
||||
for (const targetProp of properties) {
|
||||
|
@ -10425,7 +10439,7 @@ namespace ts {
|
|||
* Leave signatures alone since they are not subject to the check.
|
||||
*/
|
||||
function getRegularTypeOfObjectLiteral(type: Type): Type {
|
||||
if (!(getObjectFlags(type) & ObjectFlags.ObjectLiteral && type.flags & TypeFlags.FreshLiteral)) {
|
||||
if (!(isObjectLiteralType(type) && type.flags & TypeFlags.FreshLiteral)) {
|
||||
return type;
|
||||
}
|
||||
const regularType = (<FreshObjectLiteralType>type).regularType;
|
||||
|
@ -10447,18 +10461,74 @@ namespace ts {
|
|||
return regularNew;
|
||||
}
|
||||
|
||||
function getWidenedProperty(prop: Symbol): Symbol {
|
||||
function createWideningContext(parent: WideningContext, propertyName: __String, siblings: Type[]): WideningContext {
|
||||
return { parent, propertyName, siblings, resolvedPropertyNames: undefined };
|
||||
}
|
||||
|
||||
function getSiblingsOfContext(context: WideningContext): Type[] {
|
||||
if (!context.siblings) {
|
||||
const siblings: Type[] = [];
|
||||
for (const type of getSiblingsOfContext(context.parent)) {
|
||||
if (isObjectLiteralType(type)) {
|
||||
const prop = getPropertyOfObjectType(type, context.propertyName);
|
||||
if (prop) {
|
||||
forEachType(getTypeOfSymbol(prop), t => {
|
||||
siblings.push(t);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
context.siblings = siblings;
|
||||
}
|
||||
return context.siblings;
|
||||
}
|
||||
|
||||
function getPropertyNamesOfContext(context: WideningContext): __String[] {
|
||||
if (!context.resolvedPropertyNames) {
|
||||
const names = createMap<boolean>() as UnderscoreEscapedMap<boolean>;
|
||||
for (const t of getSiblingsOfContext(context)) {
|
||||
if (isObjectLiteralType(t) && !(getObjectFlags(t) & ObjectFlags.ContainsSpread)) {
|
||||
for (const prop of getPropertiesOfType(t)) {
|
||||
names.set(prop.escapedName, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
context.resolvedPropertyNames = arrayFrom(names.keys());
|
||||
}
|
||||
return context.resolvedPropertyNames;
|
||||
}
|
||||
|
||||
function getWidenedProperty(prop: Symbol, context: WideningContext): Symbol {
|
||||
const original = getTypeOfSymbol(prop);
|
||||
const widened = getWidenedType(original);
|
||||
const propContext = context && createWideningContext(context, prop.escapedName, /*siblings*/ undefined);
|
||||
const widened = getWidenedTypeWithContext(original, propContext);
|
||||
return widened === original ? prop : createSymbolWithType(prop, widened);
|
||||
}
|
||||
|
||||
function getWidenedTypeOfObjectLiteral(type: Type): Type {
|
||||
function getUndefinedProperty(name: __String) {
|
||||
const cached = undefinedProperties.get(name);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
const result = createSymbol(SymbolFlags.Property | SymbolFlags.Optional, name);
|
||||
result.type = undefinedType;
|
||||
undefinedProperties.set(name, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
function getWidenedTypeOfObjectLiteral(type: Type, context: WideningContext): Type {
|
||||
const members = createSymbolTable();
|
||||
for (const prop of getPropertiesOfObjectType(type)) {
|
||||
// Since get accessors already widen their return value there is no need to
|
||||
// widen accessor based properties here.
|
||||
members.set(prop.escapedName, prop.flags & SymbolFlags.Property ? getWidenedProperty(prop) : prop);
|
||||
members.set(prop.escapedName, prop.flags & SymbolFlags.Property ? getWidenedProperty(prop, context) : prop);
|
||||
}
|
||||
if (context) {
|
||||
for (const name of getPropertyNamesOfContext(context)) {
|
||||
if (!members.has(name)) {
|
||||
members.set(name, getUndefinedProperty(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
const stringIndexInfo = getIndexInfoOfType(type, IndexKind.String);
|
||||
const numberIndexInfo = getIndexInfoOfType(type, IndexKind.Number);
|
||||
|
@ -10467,20 +10537,25 @@ namespace ts {
|
|||
numberIndexInfo && createIndexInfo(getWidenedType(numberIndexInfo.type), numberIndexInfo.isReadonly));
|
||||
}
|
||||
|
||||
function getWidenedConstituentType(type: Type): Type {
|
||||
return type.flags & TypeFlags.Nullable ? type : getWidenedType(type);
|
||||
function getWidenedType(type: Type) {
|
||||
return getWidenedTypeWithContext(type, /*context*/ undefined);
|
||||
}
|
||||
|
||||
function getWidenedType(type: Type): Type {
|
||||
function getWidenedTypeWithContext(type: Type, context: WideningContext): Type {
|
||||
if (type.flags & TypeFlags.RequiresWidening) {
|
||||
if (type.flags & TypeFlags.Nullable) {
|
||||
return anyType;
|
||||
}
|
||||
if (getObjectFlags(type) & ObjectFlags.ObjectLiteral) {
|
||||
return getWidenedTypeOfObjectLiteral(type);
|
||||
if (isObjectLiteralType(type)) {
|
||||
return getWidenedTypeOfObjectLiteral(type, context);
|
||||
}
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
return getUnionType(sameMap((<UnionType>type).types, getWidenedConstituentType));
|
||||
const unionContext = context || createWideningContext(/*parent*/ undefined, /*propertyName*/ undefined, (<UnionType>type).types);
|
||||
const widenedTypes = sameMap((<UnionType>type).types, t => t.flags & TypeFlags.Nullable ? t : getWidenedTypeWithContext(t, unionContext));
|
||||
// Widening an empty object literal transitions from a highly restrictive type to
|
||||
// a highly inclusive one. For that reason we perform subtype reduction here if the
|
||||
// union includes empty object types (e.g. reducing {} | string to just {}).
|
||||
return getUnionType(widenedTypes, some(widenedTypes, isEmptyObjectType));
|
||||
}
|
||||
if (isArrayType(type) || isTupleType(type)) {
|
||||
return createTypeReference((<TypeReference>type).target, sameMap((<TypeReference>type).typeArguments, getWidenedType));
|
||||
|
@ -10502,28 +10577,35 @@ namespace ts {
|
|||
*/
|
||||
function reportWideningErrorsInType(type: Type): boolean {
|
||||
let errorReported = false;
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
for (const t of (<UnionType>type).types) {
|
||||
if (reportWideningErrorsInType(t)) {
|
||||
if (type.flags & TypeFlags.ContainsWideningType) {
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
if (some((<UnionType>type).types, isEmptyObjectType)) {
|
||||
errorReported = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isArrayType(type) || isTupleType(type)) {
|
||||
for (const t of (<TypeReference>type).typeArguments) {
|
||||
if (reportWideningErrorsInType(t)) {
|
||||
errorReported = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (getObjectFlags(type) & ObjectFlags.ObjectLiteral) {
|
||||
for (const p of getPropertiesOfObjectType(type)) {
|
||||
const t = getTypeOfSymbol(p);
|
||||
if (t.flags & TypeFlags.ContainsWideningType) {
|
||||
if (!reportWideningErrorsInType(t)) {
|
||||
error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, symbolName(p), typeToString(getWidenedType(t)));
|
||||
else {
|
||||
for (const t of (<UnionType>type).types) {
|
||||
if (reportWideningErrorsInType(t)) {
|
||||
errorReported = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isArrayType(type) || isTupleType(type)) {
|
||||
for (const t of (<TypeReference>type).typeArguments) {
|
||||
if (reportWideningErrorsInType(t)) {
|
||||
errorReported = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isObjectLiteralType(type)) {
|
||||
for (const p of getPropertiesOfObjectType(type)) {
|
||||
const t = getTypeOfSymbol(p);
|
||||
if (t.flags & TypeFlags.ContainsWideningType) {
|
||||
if (!reportWideningErrorsInType(t)) {
|
||||
error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, symbolName(p), typeToString(getWidenedType(t)));
|
||||
}
|
||||
errorReported = true;
|
||||
}
|
||||
errorReported = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11029,11 +11111,28 @@ namespace ts {
|
|||
return constraint && maybeTypeOfKind(constraint, TypeFlags.Primitive | TypeFlags.Index);
|
||||
}
|
||||
|
||||
function isObjectLiteralType(type: Type) {
|
||||
return !!(getObjectFlags(type) & ObjectFlags.ObjectLiteral);
|
||||
}
|
||||
|
||||
function widenObjectLiteralCandidates(candidates: Type[]): Type[] {
|
||||
if (candidates.length > 1) {
|
||||
const objectLiterals = filter(candidates, isObjectLiteralType);
|
||||
if (objectLiterals.length) {
|
||||
const objectLiteralsType = getWidenedType(getUnionType(objectLiterals, /*subtypeReduction*/ true));
|
||||
return concatenate(filter(candidates, t => !isObjectLiteralType(t)), [objectLiteralsType]);
|
||||
}
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
|
||||
function getInferredType(context: InferenceContext, index: number): Type {
|
||||
const inference = context.inferences[index];
|
||||
let inferredType = inference.inferredType;
|
||||
if (!inferredType) {
|
||||
if (inference.candidates) {
|
||||
// Extract all object literal types and replace them with a single widened and normalized type.
|
||||
const candidates = widenObjectLiteralCandidates(inference.candidates);
|
||||
// We widen inferred literal types if
|
||||
// all inferences were made to top-level ocurrences of the type parameter, and
|
||||
// the type parameter has no constraint or its constraint includes no primitive or literal types, and
|
||||
|
@ -11042,7 +11141,7 @@ namespace ts {
|
|||
const widenLiteralTypes = inference.topLevel &&
|
||||
!hasPrimitiveConstraint(inference.typeParameter) &&
|
||||
(inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter));
|
||||
const baseCandidates = widenLiteralTypes ? sameMap(inference.candidates, getWidenedLiteralType) : inference.candidates;
|
||||
const baseCandidates = widenLiteralTypes ? sameMap(candidates, getWidenedLiteralType) : candidates;
|
||||
// If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if
|
||||
// union types were requested or if all inferences were made from the return type position, infer a
|
||||
// union type. Otherwise, infer a common supertype.
|
||||
|
|
|
@ -3327,6 +3327,7 @@ namespace ts {
|
|||
ObjectLiteral = 1 << 7, // Originates in an object literal
|
||||
EvolvingArray = 1 << 8, // Evolving array type
|
||||
ObjectLiteralPatternWithComputedProperties = 1 << 9, // Object literal pattern with computed properties
|
||||
ContainsSpread = 1 << 10, // Object literal contains spread operation
|
||||
ClassOrInterface = Class | Interface
|
||||
}
|
||||
|
||||
|
@ -3609,6 +3610,14 @@ namespace ts {
|
|||
compareTypes: TypeComparer; // Type comparer function
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface WideningContext {
|
||||
parent?: WideningContext; // Parent context
|
||||
propertyName?: __String; // Name of property in parent
|
||||
siblings?: Type[]; // Types of siblings
|
||||
resolvedPropertyNames?: __String[]; // Property names occurring in sibling object literals
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export const enum SpecialPropertyAssignmentKind {
|
||||
None,
|
||||
|
|
|
@ -2040,6 +2040,7 @@ declare namespace ts {
|
|||
ObjectLiteral = 128,
|
||||
EvolvingArray = 256,
|
||||
ObjectLiteralPatternWithComputedProperties = 512,
|
||||
ContainsSpread = 1024,
|
||||
ClassOrInterface = 3,
|
||||
}
|
||||
interface ObjectType extends Type {
|
||||
|
|
|
@ -2040,6 +2040,7 @@ declare namespace ts {
|
|||
ObjectLiteral = 128,
|
||||
EvolvingArray = 256,
|
||||
ObjectLiteralPatternWithComputedProperties = 512,
|
||||
ContainsSpread = 1024,
|
||||
ClassOrInterface = 3,
|
||||
}
|
||||
interface ObjectType extends Type {
|
||||
|
|
|
@ -4,11 +4,12 @@ tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclarati
|
|||
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,33): error TS2304: Cannot find name 'await'.
|
||||
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,38): error TS1005: ';' expected.
|
||||
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,39): error TS1128: Declaration or statement expected.
|
||||
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,41): error TS2365: Operator '>' cannot be applied to types 'boolean' and '{}'.
|
||||
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,49): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,53): error TS1109: Expression expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts (8 errors) ====
|
||||
==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts (9 errors) ====
|
||||
async function foo(a = await => await): Promise<void> {
|
||||
~~~~~~~~~
|
||||
!!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
|
||||
|
@ -22,8 +23,11 @@ tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclarati
|
|||
!!! error TS1005: ';' expected.
|
||||
~
|
||||
!!! error TS1128: Declaration or statement expected.
|
||||
~~~~~~~~~~~~~~~
|
||||
~~~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
~
|
||||
!!! error TS1109: Expression expected.
|
||||
}
|
||||
}
|
||||
~
|
||||
!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and '{}'.
|
|
@ -4,11 +4,12 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1
|
|||
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,33): error TS2304: Cannot find name 'await'.
|
||||
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,38): error TS1005: ';' expected.
|
||||
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,39): error TS1128: Declaration or statement expected.
|
||||
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,41): error TS2365: Operator '>' cannot be applied to types 'boolean' and '{}'.
|
||||
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,49): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,53): error TS1109: Expression expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts (8 errors) ====
|
||||
==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts (9 errors) ====
|
||||
async function foo(a = await => await): Promise<void> {
|
||||
~~~~~~~~~
|
||||
!!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
|
||||
|
@ -22,8 +23,11 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1
|
|||
!!! error TS1005: ';' expected.
|
||||
~
|
||||
!!! error TS1128: Declaration or statement expected.
|
||||
~~~~~~~~~~~~~~~
|
||||
~~~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
~
|
||||
!!! error TS1109: Expression expected.
|
||||
}
|
||||
}
|
||||
~
|
||||
!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and '{}'.
|
|
@ -4,11 +4,12 @@ tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration1
|
|||
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,33): error TS2304: Cannot find name 'await'.
|
||||
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,38): error TS1005: ';' expected.
|
||||
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,39): error TS1128: Declaration or statement expected.
|
||||
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,41): error TS2365: Operator '>' cannot be applied to types 'boolean' and '{}'.
|
||||
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,49): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,53): error TS1109: Expression expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts (8 errors) ====
|
||||
==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts (9 errors) ====
|
||||
async function foo(a = await => await): Promise<void> {
|
||||
~~~~~~~~~
|
||||
!!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
|
||||
|
@ -22,8 +23,11 @@ tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration1
|
|||
!!! error TS1005: ';' expected.
|
||||
~
|
||||
!!! error TS1128: Declaration or statement expected.
|
||||
~~~~~~~~~~~~~~~
|
||||
~~~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
~
|
||||
!!! error TS1109: Expression expected.
|
||||
}
|
||||
}
|
||||
~
|
||||
!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and '{}'.
|
|
@ -2,11 +2,12 @@ tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclarati
|
|||
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts(1,20): error TS2304: Cannot find name 'await'.
|
||||
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts(1,25): error TS1005: ';' expected.
|
||||
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts(1,26): error TS1128: Declaration or statement expected.
|
||||
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts(1,28): error TS2365: Operator '>' cannot be applied to types 'boolean' and '{}'.
|
||||
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts(1,36): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts(1,40): error TS1109: Expression expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts (6 errors) ====
|
||||
==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration5_es2017.ts (7 errors) ====
|
||||
async function foo(await): Promise<void> {
|
||||
~~~~~
|
||||
!!! error TS1138: Parameter declaration expected.
|
||||
|
@ -16,8 +17,11 @@ tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclarati
|
|||
!!! error TS1005: ';' expected.
|
||||
~
|
||||
!!! error TS1128: Declaration or statement expected.
|
||||
~~~~~~~~~~~~~~~
|
||||
~~~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
~
|
||||
!!! error TS1109: Expression expected.
|
||||
}
|
||||
}
|
||||
~
|
||||
!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and '{}'.
|
|
@ -2,11 +2,12 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5
|
|||
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts(1,20): error TS2304: Cannot find name 'await'.
|
||||
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts(1,25): error TS1005: ';' expected.
|
||||
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts(1,26): error TS1128: Declaration or statement expected.
|
||||
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts(1,28): error TS2365: Operator '>' cannot be applied to types 'boolean' and '{}'.
|
||||
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts(1,36): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts(1,40): error TS1109: Expression expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts (6 errors) ====
|
||||
==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5_es5.ts (7 errors) ====
|
||||
async function foo(await): Promise<void> {
|
||||
~~~~~
|
||||
!!! error TS1138: Parameter declaration expected.
|
||||
|
@ -16,8 +17,11 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration5
|
|||
!!! error TS1005: ';' expected.
|
||||
~
|
||||
!!! error TS1128: Declaration or statement expected.
|
||||
~~~~~~~~~~~~~~~
|
||||
~~~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
~
|
||||
!!! error TS1109: Expression expected.
|
||||
}
|
||||
}
|
||||
~
|
||||
!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and '{}'.
|
|
@ -2,11 +2,12 @@ tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5
|
|||
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts(1,20): error TS2304: Cannot find name 'await'.
|
||||
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts(1,25): error TS1005: ';' expected.
|
||||
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts(1,26): error TS1128: Declaration or statement expected.
|
||||
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts(1,28): error TS2365: Operator '>' cannot be applied to types 'boolean' and '{}'.
|
||||
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts(1,36): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts(1,40): error TS1109: Expression expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts (6 errors) ====
|
||||
==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts (7 errors) ====
|
||||
async function foo(await): Promise<void> {
|
||||
~~~~~
|
||||
!!! error TS1138: Parameter declaration expected.
|
||||
|
@ -16,8 +17,11 @@ tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5
|
|||
!!! error TS1005: ';' expected.
|
||||
~
|
||||
!!! error TS1128: Declaration or statement expected.
|
||||
~~~~~~~~~~~~~~~
|
||||
~~~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
~
|
||||
!!! error TS1109: Expression expected.
|
||||
}
|
||||
}
|
||||
~
|
||||
!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and '{}'.
|
|
@ -47,7 +47,7 @@ var r = true ? 1 : 2;
|
|||
|
||||
var r3 = true ? 1 : {};
|
||||
>r3 : {}
|
||||
>true ? 1 : {} : {}
|
||||
>true ? 1 : {} : 1 | {}
|
||||
>true : true
|
||||
>1 : 1
|
||||
>{} : {}
|
||||
|
|
|
@ -45,7 +45,7 @@ var result1 = true ? x : a;
|
|||
|
||||
//Expr1 and Expr2 are literals
|
||||
true ? {} : 1;
|
||||
>true ? {} : 1 : {}
|
||||
>true ? {} : 1 : 1 | {}
|
||||
>true : true
|
||||
>{} : {}
|
||||
>1 : 1
|
||||
|
@ -64,13 +64,13 @@ true ? { a: 1 } : { a: 2, b: 'string' };
|
|||
|
||||
var result2 = true ? {} : 1;
|
||||
>result2 : {}
|
||||
>true ? {} : 1 : {}
|
||||
>true ? {} : 1 : 1 | {}
|
||||
>true : true
|
||||
>{} : {}
|
||||
>1 : 1
|
||||
|
||||
var result3 = true ? { a: 1 } : { a: 2, b: 'string' };
|
||||
>result3 : { a: number; } | { a: number; b: string; }
|
||||
>result3 : { a: number; b?: undefined; } | { a: number; b: string; }
|
||||
>true ? { a: 1 } : { a: 2, b: 'string' } : { a: number; } | { a: number; b: string; }
|
||||
>true : true
|
||||
>{ a: 1 } : { a: number; }
|
||||
|
@ -125,7 +125,7 @@ var result5 = true ? a : x;
|
|||
|
||||
//Expr1 and Expr2 are literals
|
||||
true ? 1 : {};
|
||||
>true ? 1 : {} : {}
|
||||
>true ? 1 : {} : 1 | {}
|
||||
>true : true
|
||||
>1 : 1
|
||||
>{} : {}
|
||||
|
@ -144,13 +144,13 @@ true ? { a: 2, b: 'string' } : { a: 1 };
|
|||
|
||||
var result6 = true ? 1 : {};
|
||||
>result6 : {}
|
||||
>true ? 1 : {} : {}
|
||||
>true ? 1 : {} : 1 | {}
|
||||
>true : true
|
||||
>1 : 1
|
||||
>{} : {}
|
||||
|
||||
var result7 = true ? { a: 2, b: 'string' } : { a: 1 };
|
||||
>result7 : { a: number; b: string; } | { a: number; }
|
||||
>result7 : { a: number; b: string; } | { a: number; b?: undefined; }
|
||||
>true ? { a: 2, b: 'string' } : { a: 1 } : { a: number; b: string; } | { a: number; }
|
||||
>true : true
|
||||
>{ a: 2, b: 'string' } : { a: number; b: string; }
|
||||
|
|
|
@ -22,13 +22,13 @@ var c = [1, '', null]; // {}[]
|
|||
|
||||
var d = [{}, 1]; // {}[]
|
||||
>d : {}[]
|
||||
>[{}, 1] : {}[]
|
||||
>[{}, 1] : (number | {})[]
|
||||
>{} : {}
|
||||
>1 : 1
|
||||
|
||||
var e = [{}, Object]; // {}[]
|
||||
>e : {}[]
|
||||
>[{}, Object] : {}[]
|
||||
>[{}, Object] : (ObjectConstructor | {})[]
|
||||
>{} : {}
|
||||
>Object : ObjectConstructor
|
||||
|
||||
|
@ -48,7 +48,7 @@ var g = [[1], ['']]; // {}[]
|
|||
>'' : ""
|
||||
|
||||
var h = [{ foo: 1, bar: '' }, { foo: 2 }]; // {foo: number}[]
|
||||
>h : ({ foo: number; bar: string; } | { foo: number; })[]
|
||||
>h : ({ foo: number; bar: string; } | { foo: number; bar?: undefined; })[]
|
||||
>[{ foo: 1, bar: '' }, { foo: 2 }] : ({ foo: number; bar: string; } | { foo: number; })[]
|
||||
>{ foo: 1, bar: '' } : { foo: number; bar: string; }
|
||||
>foo : number
|
||||
|
@ -60,7 +60,7 @@ var h = [{ foo: 1, bar: '' }, { foo: 2 }]; // {foo: number}[]
|
|||
>2 : 2
|
||||
|
||||
var i = [{ foo: 1, bar: '' }, { foo: '' }]; // {}[]
|
||||
>i : ({ foo: number; bar: string; } | { foo: string; })[]
|
||||
>i : ({ foo: number; bar: string; } | { foo: string; bar?: undefined; })[]
|
||||
>[{ foo: 1, bar: '' }, { foo: '' }] : ({ foo: number; bar: string; } | { foo: string; })[]
|
||||
>{ foo: 1, bar: '' } : { foo: number; bar: string; }
|
||||
>foo : number
|
||||
|
@ -145,7 +145,7 @@ module Derived {
|
|||
>Derived : typeof Derived
|
||||
|
||||
var h = [{ foo: base, basear: derived }, { foo: base }]; // {foo: Base}[]
|
||||
>h : ({ foo: Base; basear: Derived; } | { foo: Base; })[]
|
||||
>h : ({ foo: Base; basear: Derived; } | { foo: Base; basear?: undefined; })[]
|
||||
>[{ foo: base, basear: derived }, { foo: base }] : ({ foo: Base; basear: Derived; } | { foo: Base; })[]
|
||||
>{ foo: base, basear: derived } : { foo: Base; basear: Derived; }
|
||||
>foo : Base
|
||||
|
@ -157,7 +157,7 @@ module Derived {
|
|||
>base : Base
|
||||
|
||||
var i = [{ foo: base, basear: derived }, { foo: derived }]; // {foo: Derived}[]
|
||||
>i : ({ foo: Base; basear: Derived; } | { foo: Derived; })[]
|
||||
>i : ({ foo: Base; basear: Derived; } | { foo: Derived; basear?: undefined; })[]
|
||||
>[{ foo: base, basear: derived }, { foo: derived }] : ({ foo: Base; basear: Derived; } | { foo: Derived; })[]
|
||||
>{ foo: base, basear: derived } : { foo: Base; basear: Derived; }
|
||||
>foo : Base
|
||||
|
|
|
@ -176,7 +176,7 @@ var o1: { a: { a: string; }; b: string; } = { e: 0, f: 0 };
|
|||
>0 : 0
|
||||
|
||||
var a1 = [{ e: 0, f: 0 }, { e: 0, f: 0 }, { e: 0, g: 0 }];
|
||||
>a1 : ({ e: number; f: number; } | { e: number; g: number; })[]
|
||||
>a1 : ({ e: number; f: number; g?: undefined; } | { e: number; g: number; f?: undefined; })[]
|
||||
>[{ e: 0, f: 0 }, { e: 0, f: 0 }, { e: 0, g: 0 }] : ({ e: number; f: number; } | { e: number; g: number; })[]
|
||||
>{ e: 0, f: 0 } : { e: number; f: number; }
|
||||
>e : number
|
||||
|
|
|
@ -107,8 +107,8 @@ function fn3<T extends { a: string; b: string }, U extends { a: string; b: numbe
|
|||
>u : U
|
||||
|
||||
var r3 = t || { a: '' };
|
||||
>r3 : { a: string; }
|
||||
>t || { a: '' } : { a: string; }
|
||||
>r3 : T | { a: string; }
|
||||
>t || { a: '' } : T | { a: string; }
|
||||
>t : T
|
||||
>{ a: '' } : { a: string; }
|
||||
>a : string
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(7,1): error TS2322: Type '{ a: number; b: number; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'.
|
||||
Type '{ a: number; b: number; }' is not assignable to type '{ a: number; b: string; c: boolean; }'.
|
||||
Property 'c' is missing in type '{ a: number; b: number; }'.
|
||||
tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(8,1): error TS2322: Type '{ b: string; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'.
|
||||
Type '{ b: string; }' is not assignable to type '{ a: number; b: string; c: boolean; }'.
|
||||
Property 'a' is missing in type '{ b: string; }'.
|
||||
tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(9,1): error TS2322: Type '{ c: true; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'.
|
||||
Type '{ c: true; }' is not assignable to type '{ a: number; b: string; c: boolean; }'.
|
||||
Property 'a' is missing in type '{ c: true; }'.
|
||||
tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(17,1): error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }'.
|
||||
Type '{ a: string; b: number; }' is not assignable to type '{ a?: undefined; b?: undefined; }'.
|
||||
Types of property 'a' are incompatible.
|
||||
Type 'string' is not assignable to type 'undefined'.
|
||||
tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(18,1): error TS2322: Type '{ a: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }'.
|
||||
Type '{ a: number; }' is not assignable to type '{ a?: undefined; b?: undefined; }'.
|
||||
Types of property 'a' are incompatible.
|
||||
Type 'number' is not assignable to type 'undefined'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts (5 errors) ====
|
||||
// Object literals in unions are normalized upon widening
|
||||
let a1 = [{ a: 0 }, { a: 1, b: "x" }, { a: 2, b: "y", c: true }][0];
|
||||
a1.a; // number
|
||||
a1.b; // string | undefined
|
||||
a1.c; // boolean | undefined
|
||||
a1 = { a: 1 };
|
||||
a1 = { a: 0, b: 0 }; // Error
|
||||
~~
|
||||
!!! error TS2322: Type '{ a: number; b: number; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'.
|
||||
!!! error TS2322: Type '{ a: number; b: number; }' is not assignable to type '{ a: number; b: string; c: boolean; }'.
|
||||
!!! error TS2322: Property 'c' is missing in type '{ a: number; b: number; }'.
|
||||
a1 = { b: "y" }; // Error
|
||||
~~
|
||||
!!! error TS2322: Type '{ b: string; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'.
|
||||
!!! error TS2322: Type '{ b: string; }' is not assignable to type '{ a: number; b: string; c: boolean; }'.
|
||||
!!! error TS2322: Property 'a' is missing in type '{ b: string; }'.
|
||||
a1 = { c: true }; // Error
|
||||
~~
|
||||
!!! error TS2322: Type '{ c: true; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'.
|
||||
!!! error TS2322: Type '{ c: true; }' is not assignable to type '{ a: number; b: string; c: boolean; }'.
|
||||
!!! error TS2322: Property 'a' is missing in type '{ c: true; }'.
|
||||
|
||||
let a2 = [{ a: 1, b: 2 }, { a: "abc" }, {}][0];
|
||||
a2.a; // string | number | undefined
|
||||
a2.b; // number | undefined
|
||||
a2 = { a: 10, b: 20 };
|
||||
a2 = { a: "def" };
|
||||
a2 = {};
|
||||
a2 = { a: "def", b: 20 }; // Error
|
||||
~~
|
||||
!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }'.
|
||||
!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a?: undefined; b?: undefined; }'.
|
||||
!!! error TS2322: Types of property 'a' are incompatible.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'undefined'.
|
||||
a2 = { a: 1 }; // Error
|
||||
~~
|
||||
!!! error TS2322: Type '{ a: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }'.
|
||||
!!! error TS2322: Type '{ a: number; }' is not assignable to type '{ a?: undefined; b?: undefined; }'.
|
||||
!!! error TS2322: Types of property 'a' are incompatible.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'undefined'.
|
||||
|
||||
// Object literals containing spreads are not normalized
|
||||
declare let b1: { a: string, b: string } | { b: string, c: string };
|
||||
let b2 = { ...b1, z: 55 };
|
||||
let b3 = { ...b2 };
|
||||
|
||||
// Before widening {} acts like { [x: string]: undefined }, which is a
|
||||
// subtype of types with all optional properties
|
||||
declare let opts: { foo?: string, bar?: string, baz?: boolean };
|
||||
let c1 = !true ? {} : opts;
|
||||
let c2 = !true ? opts : {};
|
||||
let c3 = !true ? { a: 0, b: 0 } : {};
|
||||
let c4 = !true ? {} : { a: 0, b: 0 };
|
||||
|
||||
// Normalization applies to nested properties
|
||||
let d1 = [{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }][0];
|
||||
d1.kind;
|
||||
d1.pos;
|
||||
d1.pos.x;
|
||||
d1.pos.y;
|
||||
d1.pos.a;
|
||||
d1.pos.b;
|
||||
|
||||
declare function f<T>(...items: T[]): T;
|
||||
declare let data: { a: 1, b: "abc", c: true };
|
||||
|
||||
// Object literals are inferred as a single normalized union type
|
||||
let e1 = f({ a: 1, b: 2 }, { a: "abc" }, {});
|
||||
let e2 = f({}, { a: "abc" }, { a: 1, b: 2 });
|
||||
let e3 = f(data, { a: 2 });
|
||||
let e4 = f({ a: 2 }, data);
|
||||
|
232
tests/baselines/reference/objectLiteralNormalization.js
Normal file
232
tests/baselines/reference/objectLiteralNormalization.js
Normal file
|
@ -0,0 +1,232 @@
|
|||
//// [objectLiteralNormalization.ts]
|
||||
// Object literals in unions are normalized upon widening
|
||||
let a1 = [{ a: 0 }, { a: 1, b: "x" }, { a: 2, b: "y", c: true }][0];
|
||||
a1.a; // number
|
||||
a1.b; // string | undefined
|
||||
a1.c; // boolean | undefined
|
||||
a1 = { a: 1 };
|
||||
a1 = { a: 0, b: 0 }; // Error
|
||||
a1 = { b: "y" }; // Error
|
||||
a1 = { c: true }; // Error
|
||||
|
||||
let a2 = [{ a: 1, b: 2 }, { a: "abc" }, {}][0];
|
||||
a2.a; // string | number | undefined
|
||||
a2.b; // number | undefined
|
||||
a2 = { a: 10, b: 20 };
|
||||
a2 = { a: "def" };
|
||||
a2 = {};
|
||||
a2 = { a: "def", b: 20 }; // Error
|
||||
a2 = { a: 1 }; // Error
|
||||
|
||||
// Object literals containing spreads are not normalized
|
||||
declare let b1: { a: string, b: string } | { b: string, c: string };
|
||||
let b2 = { ...b1, z: 55 };
|
||||
let b3 = { ...b2 };
|
||||
|
||||
// Before widening {} acts like { [x: string]: undefined }, which is a
|
||||
// subtype of types with all optional properties
|
||||
declare let opts: { foo?: string, bar?: string, baz?: boolean };
|
||||
let c1 = !true ? {} : opts;
|
||||
let c2 = !true ? opts : {};
|
||||
let c3 = !true ? { a: 0, b: 0 } : {};
|
||||
let c4 = !true ? {} : { a: 0, b: 0 };
|
||||
|
||||
// Normalization applies to nested properties
|
||||
let d1 = [{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }][0];
|
||||
d1.kind;
|
||||
d1.pos;
|
||||
d1.pos.x;
|
||||
d1.pos.y;
|
||||
d1.pos.a;
|
||||
d1.pos.b;
|
||||
|
||||
declare function f<T>(...items: T[]): T;
|
||||
declare let data: { a: 1, b: "abc", c: true };
|
||||
|
||||
// Object literals are inferred as a single normalized union type
|
||||
let e1 = f({ a: 1, b: 2 }, { a: "abc" }, {});
|
||||
let e2 = f({}, { a: "abc" }, { a: 1, b: 2 });
|
||||
let e3 = f(data, { a: 2 });
|
||||
let e4 = f({ a: 2 }, data);
|
||||
|
||||
|
||||
//// [objectLiteralNormalization.js]
|
||||
"use strict";
|
||||
var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
// Object literals in unions are normalized upon widening
|
||||
var a1 = [{ a: 0 }, { a: 1, b: "x" }, { a: 2, b: "y", c: true }][0];
|
||||
a1.a; // number
|
||||
a1.b; // string | undefined
|
||||
a1.c; // boolean | undefined
|
||||
a1 = { a: 1 };
|
||||
a1 = { a: 0, b: 0 }; // Error
|
||||
a1 = { b: "y" }; // Error
|
||||
a1 = { c: true }; // Error
|
||||
var a2 = [{ a: 1, b: 2 }, { a: "abc" }, {}][0];
|
||||
a2.a; // string | number | undefined
|
||||
a2.b; // number | undefined
|
||||
a2 = { a: 10, b: 20 };
|
||||
a2 = { a: "def" };
|
||||
a2 = {};
|
||||
a2 = { a: "def", b: 20 }; // Error
|
||||
a2 = { a: 1 }; // Error
|
||||
var b2 = __assign({}, b1, { z: 55 });
|
||||
var b3 = __assign({}, b2);
|
||||
var c1 = !true ? {} : opts;
|
||||
var c2 = !true ? opts : {};
|
||||
var c3 = !true ? { a: 0, b: 0 } : {};
|
||||
var c4 = !true ? {} : { a: 0, b: 0 };
|
||||
// Normalization applies to nested properties
|
||||
var d1 = [{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }][0];
|
||||
d1.kind;
|
||||
d1.pos;
|
||||
d1.pos.x;
|
||||
d1.pos.y;
|
||||
d1.pos.a;
|
||||
d1.pos.b;
|
||||
// Object literals are inferred as a single normalized union type
|
||||
var e1 = f({ a: 1, b: 2 }, { a: "abc" }, {});
|
||||
var e2 = f({}, { a: "abc" }, { a: 1, b: 2 });
|
||||
var e3 = f(data, { a: 2 });
|
||||
var e4 = f({ a: 2 }, data);
|
||||
|
||||
|
||||
//// [objectLiteralNormalization.d.ts]
|
||||
declare let a1: {
|
||||
a: number;
|
||||
b?: undefined;
|
||||
c?: undefined;
|
||||
} | {
|
||||
a: number;
|
||||
b: string;
|
||||
c?: undefined;
|
||||
} | {
|
||||
a: number;
|
||||
b: string;
|
||||
c: boolean;
|
||||
};
|
||||
declare let a2: {
|
||||
a: number;
|
||||
b: number;
|
||||
} | {
|
||||
a: string;
|
||||
b?: undefined;
|
||||
} | {
|
||||
a?: undefined;
|
||||
b?: undefined;
|
||||
};
|
||||
declare let b1: {
|
||||
a: string;
|
||||
b: string;
|
||||
} | {
|
||||
b: string;
|
||||
c: string;
|
||||
};
|
||||
declare let b2: {
|
||||
z: number;
|
||||
a: string;
|
||||
b: string;
|
||||
} | {
|
||||
z: number;
|
||||
b: string;
|
||||
c: string;
|
||||
};
|
||||
declare let b3: {
|
||||
z: number;
|
||||
a: string;
|
||||
b: string;
|
||||
} | {
|
||||
z: number;
|
||||
b: string;
|
||||
c: string;
|
||||
};
|
||||
declare let opts: {
|
||||
foo?: string;
|
||||
bar?: string;
|
||||
baz?: boolean;
|
||||
};
|
||||
declare let c1: {
|
||||
foo?: string | undefined;
|
||||
bar?: string | undefined;
|
||||
baz?: boolean | undefined;
|
||||
};
|
||||
declare let c2: {
|
||||
foo?: string | undefined;
|
||||
bar?: string | undefined;
|
||||
baz?: boolean | undefined;
|
||||
};
|
||||
declare let c3: {
|
||||
a: number;
|
||||
b: number;
|
||||
} | {
|
||||
a?: undefined;
|
||||
b?: undefined;
|
||||
};
|
||||
declare let c4: {
|
||||
a?: undefined;
|
||||
b?: undefined;
|
||||
} | {
|
||||
a: number;
|
||||
b: number;
|
||||
};
|
||||
declare let d1: {
|
||||
kind: string;
|
||||
pos: {
|
||||
x: number;
|
||||
y: number;
|
||||
a?: undefined;
|
||||
b?: undefined;
|
||||
};
|
||||
} | {
|
||||
kind: string;
|
||||
pos: {
|
||||
a: string;
|
||||
x?: undefined;
|
||||
y?: undefined;
|
||||
b?: undefined;
|
||||
} | {
|
||||
b: number;
|
||||
x?: undefined;
|
||||
y?: undefined;
|
||||
a?: undefined;
|
||||
};
|
||||
};
|
||||
declare function f<T>(...items: T[]): T;
|
||||
declare let data: {
|
||||
a: 1;
|
||||
b: "abc";
|
||||
c: true;
|
||||
};
|
||||
declare let e1: {
|
||||
a: number;
|
||||
b: number;
|
||||
} | {
|
||||
a: string;
|
||||
b?: undefined;
|
||||
} | {
|
||||
a?: undefined;
|
||||
b?: undefined;
|
||||
};
|
||||
declare let e2: {
|
||||
a?: undefined;
|
||||
b?: undefined;
|
||||
} | {
|
||||
a: string;
|
||||
b?: undefined;
|
||||
} | {
|
||||
a: number;
|
||||
b: number;
|
||||
};
|
||||
declare let e3: {
|
||||
a: number;
|
||||
};
|
||||
declare let e4: {
|
||||
a: number;
|
||||
};
|
213
tests/baselines/reference/objectLiteralNormalization.symbols
Normal file
213
tests/baselines/reference/objectLiteralNormalization.symbols
Normal file
|
@ -0,0 +1,213 @@
|
|||
=== tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts ===
|
||||
// Object literals in unions are normalized upon widening
|
||||
let a1 = [{ a: 0 }, { a: 1, b: "x" }, { a: 2, b: "y", c: true }][0];
|
||||
>a1 : Symbol(a1, Decl(objectLiteralNormalization.ts, 1, 3))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 1, 11))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 1, 21))
|
||||
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 1, 27))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 1, 39))
|
||||
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 1, 45))
|
||||
>c : Symbol(c, Decl(objectLiteralNormalization.ts, 1, 53))
|
||||
|
||||
a1.a; // number
|
||||
>a1.a : Symbol(a, Decl(objectLiteralNormalization.ts, 1, 11), Decl(objectLiteralNormalization.ts, 1, 21), Decl(objectLiteralNormalization.ts, 1, 39))
|
||||
>a1 : Symbol(a1, Decl(objectLiteralNormalization.ts, 1, 3))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 1, 11), Decl(objectLiteralNormalization.ts, 1, 21), Decl(objectLiteralNormalization.ts, 1, 39))
|
||||
|
||||
a1.b; // string | undefined
|
||||
>a1.b : Symbol(b, Decl(objectLiteralNormalization.ts, 1, 27), Decl(objectLiteralNormalization.ts, 1, 45))
|
||||
>a1 : Symbol(a1, Decl(objectLiteralNormalization.ts, 1, 3))
|
||||
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 1, 27), Decl(objectLiteralNormalization.ts, 1, 45))
|
||||
|
||||
a1.c; // boolean | undefined
|
||||
>a1.c : Symbol(c, Decl(objectLiteralNormalization.ts, 1, 53))
|
||||
>a1 : Symbol(a1, Decl(objectLiteralNormalization.ts, 1, 3))
|
||||
>c : Symbol(c, Decl(objectLiteralNormalization.ts, 1, 53))
|
||||
|
||||
a1 = { a: 1 };
|
||||
>a1 : Symbol(a1, Decl(objectLiteralNormalization.ts, 1, 3))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 5, 6))
|
||||
|
||||
a1 = { a: 0, b: 0 }; // Error
|
||||
>a1 : Symbol(a1, Decl(objectLiteralNormalization.ts, 1, 3))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 6, 6))
|
||||
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 6, 12))
|
||||
|
||||
a1 = { b: "y" }; // Error
|
||||
>a1 : Symbol(a1, Decl(objectLiteralNormalization.ts, 1, 3))
|
||||
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 7, 6))
|
||||
|
||||
a1 = { c: true }; // Error
|
||||
>a1 : Symbol(a1, Decl(objectLiteralNormalization.ts, 1, 3))
|
||||
>c : Symbol(c, Decl(objectLiteralNormalization.ts, 8, 6))
|
||||
|
||||
let a2 = [{ a: 1, b: 2 }, { a: "abc" }, {}][0];
|
||||
>a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 10, 11))
|
||||
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 10, 17))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 10, 27))
|
||||
|
||||
a2.a; // string | number | undefined
|
||||
>a2.a : Symbol(a, Decl(objectLiteralNormalization.ts, 10, 11), Decl(objectLiteralNormalization.ts, 10, 27))
|
||||
>a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 10, 11), Decl(objectLiteralNormalization.ts, 10, 27))
|
||||
|
||||
a2.b; // number | undefined
|
||||
>a2.b : Symbol(b, Decl(objectLiteralNormalization.ts, 10, 17))
|
||||
>a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3))
|
||||
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 10, 17))
|
||||
|
||||
a2 = { a: 10, b: 20 };
|
||||
>a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 13, 6))
|
||||
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 13, 13))
|
||||
|
||||
a2 = { a: "def" };
|
||||
>a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 14, 6))
|
||||
|
||||
a2 = {};
|
||||
>a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3))
|
||||
|
||||
a2 = { a: "def", b: 20 }; // Error
|
||||
>a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 16, 6))
|
||||
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 16, 16))
|
||||
|
||||
a2 = { a: 1 }; // Error
|
||||
>a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 17, 6))
|
||||
|
||||
// Object literals containing spreads are not normalized
|
||||
declare let b1: { a: string, b: string } | { b: string, c: string };
|
||||
>b1 : Symbol(b1, Decl(objectLiteralNormalization.ts, 20, 11))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 20, 17))
|
||||
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 20, 28))
|
||||
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 20, 44))
|
||||
>c : Symbol(c, Decl(objectLiteralNormalization.ts, 20, 55))
|
||||
|
||||
let b2 = { ...b1, z: 55 };
|
||||
>b2 : Symbol(b2, Decl(objectLiteralNormalization.ts, 21, 3))
|
||||
>b1 : Symbol(b1, Decl(objectLiteralNormalization.ts, 20, 11))
|
||||
>z : Symbol(z, Decl(objectLiteralNormalization.ts, 21, 17))
|
||||
|
||||
let b3 = { ...b2 };
|
||||
>b3 : Symbol(b3, Decl(objectLiteralNormalization.ts, 22, 3))
|
||||
>b2 : Symbol(b2, Decl(objectLiteralNormalization.ts, 21, 3))
|
||||
|
||||
// Before widening {} acts like { [x: string]: undefined }, which is a
|
||||
// subtype of types with all optional properties
|
||||
declare let opts: { foo?: string, bar?: string, baz?: boolean };
|
||||
>opts : Symbol(opts, Decl(objectLiteralNormalization.ts, 26, 11))
|
||||
>foo : Symbol(foo, Decl(objectLiteralNormalization.ts, 26, 19))
|
||||
>bar : Symbol(bar, Decl(objectLiteralNormalization.ts, 26, 33))
|
||||
>baz : Symbol(baz, Decl(objectLiteralNormalization.ts, 26, 47))
|
||||
|
||||
let c1 = !true ? {} : opts;
|
||||
>c1 : Symbol(c1, Decl(objectLiteralNormalization.ts, 27, 3))
|
||||
>opts : Symbol(opts, Decl(objectLiteralNormalization.ts, 26, 11))
|
||||
|
||||
let c2 = !true ? opts : {};
|
||||
>c2 : Symbol(c2, Decl(objectLiteralNormalization.ts, 28, 3))
|
||||
>opts : Symbol(opts, Decl(objectLiteralNormalization.ts, 26, 11))
|
||||
|
||||
let c3 = !true ? { a: 0, b: 0 } : {};
|
||||
>c3 : Symbol(c3, Decl(objectLiteralNormalization.ts, 29, 3))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 29, 18))
|
||||
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 29, 24))
|
||||
|
||||
let c4 = !true ? {} : { a: 0, b: 0 };
|
||||
>c4 : Symbol(c4, Decl(objectLiteralNormalization.ts, 30, 3))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 30, 23))
|
||||
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 30, 29))
|
||||
|
||||
// Normalization applies to nested properties
|
||||
let d1 = [{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }][0];
|
||||
>d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3))
|
||||
>kind : Symbol(kind, Decl(objectLiteralNormalization.ts, 33, 11))
|
||||
>pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22))
|
||||
>x : Symbol(x, Decl(objectLiteralNormalization.ts, 33, 29))
|
||||
>y : Symbol(y, Decl(objectLiteralNormalization.ts, 33, 35))
|
||||
>kind : Symbol(kind, Decl(objectLiteralNormalization.ts, 33, 47))
|
||||
>pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 58))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 33, 73))
|
||||
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 33, 86))
|
||||
|
||||
d1.kind;
|
||||
>d1.kind : Symbol(kind, Decl(objectLiteralNormalization.ts, 33, 11), Decl(objectLiteralNormalization.ts, 33, 47))
|
||||
>d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3))
|
||||
>kind : Symbol(kind, Decl(objectLiteralNormalization.ts, 33, 11), Decl(objectLiteralNormalization.ts, 33, 47))
|
||||
|
||||
d1.pos;
|
||||
>d1.pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
|
||||
>d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3))
|
||||
>pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
|
||||
|
||||
d1.pos.x;
|
||||
>d1.pos.x : Symbol(x, Decl(objectLiteralNormalization.ts, 33, 29))
|
||||
>d1.pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
|
||||
>d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3))
|
||||
>pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
|
||||
>x : Symbol(x, Decl(objectLiteralNormalization.ts, 33, 29))
|
||||
|
||||
d1.pos.y;
|
||||
>d1.pos.y : Symbol(y, Decl(objectLiteralNormalization.ts, 33, 35))
|
||||
>d1.pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
|
||||
>d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3))
|
||||
>pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
|
||||
>y : Symbol(y, Decl(objectLiteralNormalization.ts, 33, 35))
|
||||
|
||||
d1.pos.a;
|
||||
>d1.pos.a : Symbol(a, Decl(objectLiteralNormalization.ts, 33, 73))
|
||||
>d1.pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
|
||||
>d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3))
|
||||
>pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 33, 73))
|
||||
|
||||
d1.pos.b;
|
||||
>d1.pos.b : Symbol(b, Decl(objectLiteralNormalization.ts, 33, 86))
|
||||
>d1.pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
|
||||
>d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3))
|
||||
>pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
|
||||
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 33, 86))
|
||||
|
||||
declare function f<T>(...items: T[]): T;
|
||||
>f : Symbol(f, Decl(objectLiteralNormalization.ts, 39, 9))
|
||||
>T : Symbol(T, Decl(objectLiteralNormalization.ts, 41, 19))
|
||||
>items : Symbol(items, Decl(objectLiteralNormalization.ts, 41, 22))
|
||||
>T : Symbol(T, Decl(objectLiteralNormalization.ts, 41, 19))
|
||||
>T : Symbol(T, Decl(objectLiteralNormalization.ts, 41, 19))
|
||||
|
||||
declare let data: { a: 1, b: "abc", c: true };
|
||||
>data : Symbol(data, Decl(objectLiteralNormalization.ts, 42, 11))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 42, 19))
|
||||
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 42, 25))
|
||||
>c : Symbol(c, Decl(objectLiteralNormalization.ts, 42, 35))
|
||||
|
||||
// Object literals are inferred as a single normalized union type
|
||||
let e1 = f({ a: 1, b: 2 }, { a: "abc" }, {});
|
||||
>e1 : Symbol(e1, Decl(objectLiteralNormalization.ts, 45, 3))
|
||||
>f : Symbol(f, Decl(objectLiteralNormalization.ts, 39, 9))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 45, 12))
|
||||
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 45, 18))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 45, 28))
|
||||
|
||||
let e2 = f({}, { a: "abc" }, { a: 1, b: 2 });
|
||||
>e2 : Symbol(e2, Decl(objectLiteralNormalization.ts, 46, 3))
|
||||
>f : Symbol(f, Decl(objectLiteralNormalization.ts, 39, 9))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 46, 16))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 46, 30))
|
||||
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 46, 36))
|
||||
|
||||
let e3 = f(data, { a: 2 });
|
||||
>e3 : Symbol(e3, Decl(objectLiteralNormalization.ts, 47, 3))
|
||||
>f : Symbol(f, Decl(objectLiteralNormalization.ts, 39, 9))
|
||||
>data : Symbol(data, Decl(objectLiteralNormalization.ts, 42, 11))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 47, 18))
|
||||
|
||||
let e4 = f({ a: 2 }, data);
|
||||
>e4 : Symbol(e4, Decl(objectLiteralNormalization.ts, 48, 3))
|
||||
>f : Symbol(f, Decl(objectLiteralNormalization.ts, 39, 9))
|
||||
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 48, 12))
|
||||
>data : Symbol(data, Decl(objectLiteralNormalization.ts, 42, 11))
|
||||
|
326
tests/baselines/reference/objectLiteralNormalization.types
Normal file
326
tests/baselines/reference/objectLiteralNormalization.types
Normal file
|
@ -0,0 +1,326 @@
|
|||
=== tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts ===
|
||||
// Object literals in unions are normalized upon widening
|
||||
let a1 = [{ a: 0 }, { a: 1, b: "x" }, { a: 2, b: "y", c: true }][0];
|
||||
>a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }
|
||||
>[{ a: 0 }, { a: 1, b: "x" }, { a: 2, b: "y", c: true }][0] : { a: number; } | { a: number; b: string; } | { a: number; b: string; c: boolean; }
|
||||
>[{ a: 0 }, { a: 1, b: "x" }, { a: 2, b: "y", c: true }] : ({ a: number; } | { a: number; b: string; } | { a: number; b: string; c: boolean; })[]
|
||||
>{ a: 0 } : { a: number; }
|
||||
>a : number
|
||||
>0 : 0
|
||||
>{ a: 1, b: "x" } : { a: number; b: string; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
>b : string
|
||||
>"x" : "x"
|
||||
>{ a: 2, b: "y", c: true } : { a: number; b: string; c: boolean; }
|
||||
>a : number
|
||||
>2 : 2
|
||||
>b : string
|
||||
>"y" : "y"
|
||||
>c : boolean
|
||||
>true : true
|
||||
>0 : 0
|
||||
|
||||
a1.a; // number
|
||||
>a1.a : number
|
||||
>a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }
|
||||
>a : number
|
||||
|
||||
a1.b; // string | undefined
|
||||
>a1.b : string | undefined
|
||||
>a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }
|
||||
>b : string | undefined
|
||||
|
||||
a1.c; // boolean | undefined
|
||||
>a1.c : boolean | undefined
|
||||
>a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }
|
||||
>c : boolean | undefined
|
||||
|
||||
a1 = { a: 1 };
|
||||
>a1 = { a: 1 } : { a: number; }
|
||||
>a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }
|
||||
>{ a: 1 } : { a: number; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
|
||||
a1 = { a: 0, b: 0 }; // Error
|
||||
>a1 = { a: 0, b: 0 } : { a: number; b: number; }
|
||||
>a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }
|
||||
>{ a: 0, b: 0 } : { a: number; b: number; }
|
||||
>a : number
|
||||
>0 : 0
|
||||
>b : number
|
||||
>0 : 0
|
||||
|
||||
a1 = { b: "y" }; // Error
|
||||
>a1 = { b: "y" } : { b: string; }
|
||||
>a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }
|
||||
>{ b: "y" } : { b: string; }
|
||||
>b : string
|
||||
>"y" : "y"
|
||||
|
||||
a1 = { c: true }; // Error
|
||||
>a1 = { c: true } : { c: true; }
|
||||
>a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }
|
||||
>{ c: true } : { c: true; }
|
||||
>c : boolean
|
||||
>true : true
|
||||
|
||||
let a2 = [{ a: 1, b: 2 }, { a: "abc" }, {}][0];
|
||||
>a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
|
||||
>[{ a: 1, b: 2 }, { a: "abc" }, {}][0] : { a: number; b: number; } | { a: string; } | {}
|
||||
>[{ a: 1, b: 2 }, { a: "abc" }, {}] : ({ a: number; b: number; } | { a: string; } | {})[]
|
||||
>{ a: 1, b: 2 } : { a: number; b: number; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
>b : number
|
||||
>2 : 2
|
||||
>{ a: "abc" } : { a: string; }
|
||||
>a : string
|
||||
>"abc" : "abc"
|
||||
>{} : {}
|
||||
>0 : 0
|
||||
|
||||
a2.a; // string | number | undefined
|
||||
>a2.a : string | number | undefined
|
||||
>a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
|
||||
>a : string | number | undefined
|
||||
|
||||
a2.b; // number | undefined
|
||||
>a2.b : number | undefined
|
||||
>a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
|
||||
>b : number | undefined
|
||||
|
||||
a2 = { a: 10, b: 20 };
|
||||
>a2 = { a: 10, b: 20 } : { a: number; b: number; }
|
||||
>a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
|
||||
>{ a: 10, b: 20 } : { a: number; b: number; }
|
||||
>a : number
|
||||
>10 : 10
|
||||
>b : number
|
||||
>20 : 20
|
||||
|
||||
a2 = { a: "def" };
|
||||
>a2 = { a: "def" } : { a: string; }
|
||||
>a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
|
||||
>{ a: "def" } : { a: string; }
|
||||
>a : string
|
||||
>"def" : "def"
|
||||
|
||||
a2 = {};
|
||||
>a2 = {} : {}
|
||||
>a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
|
||||
>{} : {}
|
||||
|
||||
a2 = { a: "def", b: 20 }; // Error
|
||||
>a2 = { a: "def", b: 20 } : { a: string; b: number; }
|
||||
>a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
|
||||
>{ a: "def", b: 20 } : { a: string; b: number; }
|
||||
>a : string
|
||||
>"def" : "def"
|
||||
>b : number
|
||||
>20 : 20
|
||||
|
||||
a2 = { a: 1 }; // Error
|
||||
>a2 = { a: 1 } : { a: number; }
|
||||
>a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
|
||||
>{ a: 1 } : { a: number; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
|
||||
// Object literals containing spreads are not normalized
|
||||
declare let b1: { a: string, b: string } | { b: string, c: string };
|
||||
>b1 : { a: string; b: string; } | { b: string; c: string; }
|
||||
>a : string
|
||||
>b : string
|
||||
>b : string
|
||||
>c : string
|
||||
|
||||
let b2 = { ...b1, z: 55 };
|
||||
>b2 : { z: number; a: string; b: string; } | { z: number; b: string; c: string; }
|
||||
>{ ...b1, z: 55 } : { z: number; a: string; b: string; } | { z: number; b: string; c: string; }
|
||||
>b1 : { a: string; b: string; } | { b: string; c: string; }
|
||||
>z : number
|
||||
>55 : 55
|
||||
|
||||
let b3 = { ...b2 };
|
||||
>b3 : { z: number; a: string; b: string; } | { z: number; b: string; c: string; }
|
||||
>{ ...b2 } : { z: number; a: string; b: string; } | { z: number; b: string; c: string; }
|
||||
>b2 : { z: number; a: string; b: string; } | { z: number; b: string; c: string; }
|
||||
|
||||
// Before widening {} acts like { [x: string]: undefined }, which is a
|
||||
// subtype of types with all optional properties
|
||||
declare let opts: { foo?: string, bar?: string, baz?: boolean };
|
||||
>opts : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; }
|
||||
>foo : string | undefined
|
||||
>bar : string | undefined
|
||||
>baz : boolean | undefined
|
||||
|
||||
let c1 = !true ? {} : opts;
|
||||
>c1 : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; }
|
||||
>!true ? {} : opts : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; }
|
||||
>!true : false
|
||||
>true : true
|
||||
>{} : {}
|
||||
>opts : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; }
|
||||
|
||||
let c2 = !true ? opts : {};
|
||||
>c2 : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; }
|
||||
>!true ? opts : {} : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; }
|
||||
>!true : false
|
||||
>true : true
|
||||
>opts : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; }
|
||||
>{} : {}
|
||||
|
||||
let c3 = !true ? { a: 0, b: 0 } : {};
|
||||
>c3 : { a: number; b: number; } | { a?: undefined; b?: undefined; }
|
||||
>!true ? { a: 0, b: 0 } : {} : { a: number; b: number; } | {}
|
||||
>!true : false
|
||||
>true : true
|
||||
>{ a: 0, b: 0 } : { a: number; b: number; }
|
||||
>a : number
|
||||
>0 : 0
|
||||
>b : number
|
||||
>0 : 0
|
||||
>{} : {}
|
||||
|
||||
let c4 = !true ? {} : { a: 0, b: 0 };
|
||||
>c4 : { a?: undefined; b?: undefined; } | { a: number; b: number; }
|
||||
>!true ? {} : { a: 0, b: 0 } : {} | { a: number; b: number; }
|
||||
>!true : false
|
||||
>true : true
|
||||
>{} : {}
|
||||
>{ a: 0, b: 0 } : { a: number; b: number; }
|
||||
>a : number
|
||||
>0 : 0
|
||||
>b : number
|
||||
>0 : 0
|
||||
|
||||
// Normalization applies to nested properties
|
||||
let d1 = [{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }][0];
|
||||
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; }
|
||||
>[{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }][0] : { kind: string; pos: { x: number; y: number; }; } | { kind: string; pos: { a: string; } | { b: number; }; }
|
||||
>[{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }] : ({ kind: string; pos: { x: number; y: number; }; } | { kind: string; pos: { a: string; } | { b: number; }; })[]
|
||||
>{ kind: 'a', pos: { x: 0, y: 0 } } : { kind: string; pos: { x: number; y: number; }; }
|
||||
>kind : string
|
||||
>'a' : "a"
|
||||
>pos : { x: number; y: number; }
|
||||
>{ x: 0, y: 0 } : { x: number; y: number; }
|
||||
>x : number
|
||||
>0 : 0
|
||||
>y : number
|
||||
>0 : 0
|
||||
>{ kind: 'b', pos: !true ? { a: "x" } : { b: 0 } } : { kind: string; pos: { a: string; } | { b: number; }; }
|
||||
>kind : string
|
||||
>'b' : "b"
|
||||
>pos : { a: string; } | { b: number; }
|
||||
>!true ? { a: "x" } : { b: 0 } : { a: string; } | { b: number; }
|
||||
>!true : false
|
||||
>true : true
|
||||
>{ a: "x" } : { a: string; }
|
||||
>a : string
|
||||
>"x" : "x"
|
||||
>{ b: 0 } : { b: number; }
|
||||
>b : number
|
||||
>0 : 0
|
||||
>0 : 0
|
||||
|
||||
d1.kind;
|
||||
>d1.kind : string
|
||||
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; }
|
||||
>kind : string
|
||||
|
||||
d1.pos;
|
||||
>d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
|
||||
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; }
|
||||
>pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
|
||||
|
||||
d1.pos.x;
|
||||
>d1.pos.x : number | undefined
|
||||
>d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
|
||||
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; }
|
||||
>pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
|
||||
>x : number | undefined
|
||||
|
||||
d1.pos.y;
|
||||
>d1.pos.y : number | undefined
|
||||
>d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
|
||||
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; }
|
||||
>pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
|
||||
>y : number | undefined
|
||||
|
||||
d1.pos.a;
|
||||
>d1.pos.a : string | undefined
|
||||
>d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
|
||||
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; }
|
||||
>pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
|
||||
>a : string | undefined
|
||||
|
||||
d1.pos.b;
|
||||
>d1.pos.b : number | undefined
|
||||
>d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
|
||||
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; }
|
||||
>pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
|
||||
>b : number | undefined
|
||||
|
||||
declare function f<T>(...items: T[]): T;
|
||||
>f : <T>(...items: T[]) => T
|
||||
>T : T
|
||||
>items : T[]
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
declare let data: { a: 1, b: "abc", c: true };
|
||||
>data : { a: 1; b: "abc"; c: true; }
|
||||
>a : 1
|
||||
>b : "abc"
|
||||
>c : true
|
||||
>true : true
|
||||
|
||||
// Object literals are inferred as a single normalized union type
|
||||
let e1 = f({ a: 1, b: 2 }, { a: "abc" }, {});
|
||||
>e1 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
|
||||
>f({ a: 1, b: 2 }, { a: "abc" }, {}) : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
|
||||
>f : <T>(...items: T[]) => T
|
||||
>{ a: 1, b: 2 } : { a: number; b: number; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
>b : number
|
||||
>2 : 2
|
||||
>{ a: "abc" } : { a: string; }
|
||||
>a : string
|
||||
>"abc" : "abc"
|
||||
>{} : {}
|
||||
|
||||
let e2 = f({}, { a: "abc" }, { a: 1, b: 2 });
|
||||
>e2 : { a?: undefined; b?: undefined; } | { a: string; b?: undefined; } | { a: number; b: number; }
|
||||
>f({}, { a: "abc" }, { a: 1, b: 2 }) : { a?: undefined; b?: undefined; } | { a: string; b?: undefined; } | { a: number; b: number; }
|
||||
>f : <T>(...items: T[]) => T
|
||||
>{} : {}
|
||||
>{ a: "abc" } : { a: string; }
|
||||
>a : string
|
||||
>"abc" : "abc"
|
||||
>{ a: 1, b: 2 } : { a: number; b: number; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
>b : number
|
||||
>2 : 2
|
||||
|
||||
let e3 = f(data, { a: 2 });
|
||||
>e3 : { a: number; }
|
||||
>f(data, { a: 2 }) : { a: number; }
|
||||
>f : <T>(...items: T[]) => T
|
||||
>data : { a: 1; b: "abc"; c: true; }
|
||||
>{ a: 2 } : { a: number; }
|
||||
>a : number
|
||||
>2 : 2
|
||||
|
||||
let e4 = f({ a: 2 }, data);
|
||||
>e4 : { a: number; }
|
||||
>f({ a: 2 }, data) : { a: number; }
|
||||
>f : <T>(...items: T[]) => T
|
||||
>{ a: 2 } : { a: number; }
|
||||
>a : number
|
||||
>2 : 2
|
||||
>data : { a: 1; b: "abc"; c: true; }
|
||||
|
|
@ -295,7 +295,7 @@ function conditionalSpreadBoolean(b: boolean) : { x: number, y: number } {
|
|||
>14 : 14
|
||||
}
|
||||
let o2 = { ...b && { x: 21 }}
|
||||
>o2 : {} | { x: number; }
|
||||
>o2 : {}
|
||||
>{ ...b && { x: 21 }} : {} | { x: number; }
|
||||
>b && { x: 21 } : false | { x: number; }
|
||||
>b : boolean
|
||||
|
@ -336,7 +336,7 @@ function conditionalSpreadNumber(nt: number): { x: number, y: number } {
|
|||
>nt : number
|
||||
}
|
||||
let o2 = { ...nt && { x: nt }}
|
||||
>o2 : {} | { x: number; }
|
||||
>o2 : {}
|
||||
>{ ...nt && { x: nt }} : {} | { x: number; }
|
||||
>nt && { x: nt } : 0 | { x: number; }
|
||||
>nt : number
|
||||
|
@ -377,7 +377,7 @@ function conditionalSpreadString(st: string): { x: string, y: number } {
|
|||
>st : string
|
||||
}
|
||||
let o2 = { ...st && { x: st }}
|
||||
>o2 : {} | { x: string; }
|
||||
>o2 : {}
|
||||
>{ ...st && { x: st }} : {} | { x: string; }
|
||||
>st && { x: st } : "" | { x: string; }
|
||||
>st : string
|
||||
|
|
|
@ -78,7 +78,7 @@ var b: Boolean = true;
|
|||
|
||||
var n3 = 5 || {};
|
||||
>n3 : {}
|
||||
>5 || {} : {}
|
||||
>5 || {} : 5 | {}
|
||||
>5 : 5
|
||||
>{} : {}
|
||||
|
||||
|
|
41
tests/baselines/reference/spreadUnion2.errors.txt
Normal file
41
tests/baselines/reference/spreadUnion2.errors.txt
Normal file
|
@ -0,0 +1,41 @@
|
|||
tests/cases/conformance/types/spread/spreadUnion2.ts(5,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'o1' has type '{} | { a: number; }' at tests/cases/conformance/types/spread/spreadUnion2.ts 3:4, but here has type '{}'.
|
||||
tests/cases/conformance/types/spread/spreadUnion2.ts(8,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'o2' has type '{} | { b: number; }' at tests/cases/conformance/types/spread/spreadUnion2.ts 6:4, but here has type '{}'.
|
||||
tests/cases/conformance/types/spread/spreadUnion2.ts(11,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'o3' has type '{} | { a: number; } | { b: number; } | { a: number; b: number; }' at tests/cases/conformance/types/spread/spreadUnion2.ts 9:4, but here has type '{}'.
|
||||
tests/cases/conformance/types/spread/spreadUnion2.ts(12,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'o3' has type '{} | { a: number; } | { b: number; } | { a: number; b: number; }' at tests/cases/conformance/types/spread/spreadUnion2.ts 9:4, but here has type '{}'.
|
||||
tests/cases/conformance/types/spread/spreadUnion2.ts(15,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'o4' has type '{} | { a: number; }' at tests/cases/conformance/types/spread/spreadUnion2.ts 13:4, but here has type '{}'.
|
||||
tests/cases/conformance/types/spread/spreadUnion2.ts(18,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'o5' has type '{} | { b: number; }' at tests/cases/conformance/types/spread/spreadUnion2.ts 16:4, but here has type '{}'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/spread/spreadUnion2.ts (6 errors) ====
|
||||
declare const undefinedUnion: { a: number } | undefined;
|
||||
declare const nullUnion: { b: number } | null;
|
||||
|
||||
var o1: {} | { a: number };
|
||||
var o1 = { ...undefinedUnion };
|
||||
~~
|
||||
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'o1' has type '{} | { a: number; }' at tests/cases/conformance/types/spread/spreadUnion2.ts 3:4, but here has type '{}'.
|
||||
|
||||
var o2: {} | { b: number };
|
||||
var o2 = { ...nullUnion };
|
||||
~~
|
||||
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'o2' has type '{} | { b: number; }' at tests/cases/conformance/types/spread/spreadUnion2.ts 6:4, but here has type '{}'.
|
||||
|
||||
var o3: {} | { a: number } | { b: number } | { a: number, b: number };
|
||||
var o3 = { ...undefinedUnion, ...nullUnion };
|
||||
~~
|
||||
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'o3' has type '{} | { a: number; } | { b: number; } | { a: number; b: number; }' at tests/cases/conformance/types/spread/spreadUnion2.ts 9:4, but here has type '{}'.
|
||||
var o3 = { ...nullUnion, ...undefinedUnion };
|
||||
~~
|
||||
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'o3' has type '{} | { a: number; } | { b: number; } | { a: number; b: number; }' at tests/cases/conformance/types/spread/spreadUnion2.ts 9:4, but here has type '{}'.
|
||||
|
||||
var o4: {} | { a: number };
|
||||
var o4 = { ...undefinedUnion, ...undefinedUnion };
|
||||
~~
|
||||
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'o4' has type '{} | { a: number; }' at tests/cases/conformance/types/spread/spreadUnion2.ts 13:4, but here has type '{}'.
|
||||
|
||||
var o5: {} | { b: number };
|
||||
var o5 = { ...nullUnion, ...nullUnion };
|
||||
~~
|
||||
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'o5' has type '{} | { b: number; }' at tests/cases/conformance/types/spread/spreadUnion2.ts 16:4, but here has type '{}'.
|
||||
|
||||
|
|
@ -2,8 +2,7 @@ tests/cases/conformance/types/spread/spreadUnion3.ts(2,5): error TS2322: Type '{
|
|||
Type '{ y: number; }' is not assignable to type '{ y: string; }'.
|
||||
Types of property 'y' are incompatible.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/types/spread/spreadUnion3.ts(9,23): error TS2339: Property 'a' does not exist on type '{} | {} | { a: number; }'.
|
||||
Property 'a' does not exist on type '{}'.
|
||||
tests/cases/conformance/types/spread/spreadUnion3.ts(9,23): error TS2339: Property 'a' does not exist on type '{}'.
|
||||
tests/cases/conformance/types/spread/spreadUnion3.ts(17,11): error TS2698: Spread types may only be created from object types.
|
||||
tests/cases/conformance/types/spread/spreadUnion3.ts(18,11): error TS2698: Spread types may only be created from object types.
|
||||
|
||||
|
@ -24,8 +23,7 @@ tests/cases/conformance/types/spread/spreadUnion3.ts(18,11): error TS2698: Sprea
|
|||
let b = { ...t };
|
||||
let c: number = b.a; // might not have 'a'
|
||||
~
|
||||
!!! error TS2339: Property 'a' does not exist on type '{} | {} | { a: number; }'.
|
||||
!!! error TS2339: Property 'a' does not exist on type '{}'.
|
||||
!!! error TS2339: Property 'a' does not exist on type '{}'.
|
||||
}
|
||||
g()
|
||||
g(undefined)
|
||||
|
|
|
@ -24,14 +24,14 @@ function g(t?: { a: number } | null): void {
|
|||
>null : null
|
||||
|
||||
let b = { ...t };
|
||||
>b : {} | {} | { a: number; }
|
||||
>b : {}
|
||||
>{ ...t } : {} | {} | { a: number; }
|
||||
>t : { a: number; } | null | undefined
|
||||
|
||||
let c: number = b.a; // might not have 'a'
|
||||
>c : number
|
||||
>b.a : any
|
||||
>b : {} | {} | { a: number; }
|
||||
>b : {}
|
||||
>a : any
|
||||
}
|
||||
g()
|
||||
|
|
|
@ -676,14 +676,14 @@ function f21<T extends Number>(x: T) {
|
|||
|
||||
var r20 = true ? {} : x; // ok
|
||||
>r20 : {}
|
||||
>true ? {} : x : {}
|
||||
>true ? {} : x : T | {}
|
||||
>true : true
|
||||
>{} : {}
|
||||
>x : T
|
||||
|
||||
var r20 = true ? x : {}; // ok
|
||||
>r20 : {}
|
||||
>true ? x : {} : {}
|
||||
>true ? x : {} : T | {}
|
||||
>true : true
|
||||
>x : T
|
||||
>{} : {}
|
||||
|
|
|
@ -13,8 +13,8 @@ Symbol instanceof Symbol();
|
|||
|
||||
(Symbol() || {}) instanceof Object; // This one should be okay, it's a valid way of distinguishing types
|
||||
>(Symbol() || {}) instanceof Object : boolean
|
||||
>(Symbol() || {}) : {}
|
||||
>Symbol() || {} : {}
|
||||
>(Symbol() || {}) : symbol | {}
|
||||
>Symbol() || {} : symbol | {}
|
||||
>Symbol() : symbol
|
||||
>Symbol : SymbolConstructor
|
||||
>{} : {}
|
||||
|
@ -23,8 +23,8 @@ Symbol instanceof Symbol();
|
|||
Symbol instanceof (Symbol() || {});
|
||||
>Symbol instanceof (Symbol() || {}) : boolean
|
||||
>Symbol : SymbolConstructor
|
||||
>(Symbol() || {}) : {}
|
||||
>Symbol() || {} : {}
|
||||
>(Symbol() || {}) : symbol | {}
|
||||
>Symbol() || {} : symbol | {}
|
||||
>Symbol() : symbol
|
||||
>Symbol : SymbolConstructor
|
||||
>{} : {}
|
||||
|
|
|
@ -33,7 +33,7 @@ s || 1;
|
|||
>1 : 1
|
||||
|
||||
({}) || s;
|
||||
>({}) || s : {}
|
||||
>({}) || s : symbol | {}
|
||||
>({}) : {}
|
||||
>{} : {}
|
||||
>s : symbol
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInference.ts(62,36): error TS2345: Argument of type '0' is not assignable to parameter of type '""'.
|
||||
tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInference.ts(75,79): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: Date; }'.
|
||||
Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: Date; }'.
|
||||
tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInference.ts(76,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' has type '{ x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }' at tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInference.ts 74:4, but here has type '{}'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInference.ts (2 errors) ====
|
||||
|
@ -81,10 +80,9 @@ tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInference
|
|||
}
|
||||
|
||||
var a9e = someGenerics9 `${ undefined }${ { x: 6, z: new Date() } }${ { x: 6, y: '' } }`;
|
||||
~~~~~
|
||||
!!! error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: Date; }'.
|
||||
!!! error TS2345: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: Date; }'.
|
||||
var a9e: {};
|
||||
~~~
|
||||
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' has type '{ x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }' at tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInference.ts 74:4, but here has type '{}'.
|
||||
|
||||
// Generic tag with multiple parameters of generic type passed arguments with a single best common type
|
||||
var a9d = someGenerics9 `${ { x: 3 }}${ { x: 6 }}${ { x: 6 } }`;
|
||||
|
|
|
@ -395,8 +395,8 @@ interface A92 {
|
|||
}
|
||||
|
||||
var a9e = someGenerics9 `${ undefined }${ { x: 6, z: new Date() } }${ { x: 6, y: '' } }`;
|
||||
>a9e : any
|
||||
>someGenerics9 `${ undefined }${ { x: 6, z: new Date() } }${ { x: 6, y: '' } }` : any
|
||||
>a9e : { x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }
|
||||
>someGenerics9 `${ undefined }${ { x: 6, z: new Date() } }${ { x: 6, y: '' } }` : { x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }
|
||||
>someGenerics9 : <T>(strs: TemplateStringsArray, a: T, b: T, c: T) => T
|
||||
>`${ undefined }${ { x: 6, z: new Date() } }${ { x: 6, y: '' } }` : string
|
||||
>undefined : undefined
|
||||
|
@ -413,7 +413,7 @@ var a9e = someGenerics9 `${ undefined }${ { x: 6, z: new Date() } }${ { x: 6, y:
|
|||
>'' : ""
|
||||
|
||||
var a9e: {};
|
||||
>a9e : any
|
||||
>a9e : { x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }
|
||||
|
||||
// Generic tag with multiple parameters of generic type passed arguments with a single best common type
|
||||
var a9d = someGenerics9 `${ { x: 3 }}${ { x: 6 }}${ { x: 6 } }`;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInferenceES6.ts(62,36): error TS2345: Argument of type '0' is not assignable to parameter of type '""'.
|
||||
tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInferenceES6.ts(75,79): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: Date; }'.
|
||||
Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: Date; }'.
|
||||
tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInferenceES6.ts(76,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' has type '{ x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }' at tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInferenceES6.ts 74:4, but here has type '{}'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInferenceES6.ts (2 errors) ====
|
||||
|
@ -81,10 +80,9 @@ tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInference
|
|||
}
|
||||
|
||||
var a9e = someGenerics9 `${ undefined }${ { x: 6, z: new Date() } }${ { x: 6, y: '' } }`;
|
||||
~~~~~
|
||||
!!! error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: Date; }'.
|
||||
!!! error TS2345: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: Date; }'.
|
||||
var a9e: {};
|
||||
~~~
|
||||
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' has type '{ x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }' at tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInferenceES6.ts 74:4, but here has type '{}'.
|
||||
|
||||
// Generic tag with multiple parameters of generic type passed arguments with a single best common type
|
||||
var a9d = someGenerics9 `${ { x: 3 }}${ { x: 6 }}${ { x: 6 } }`;
|
||||
|
|
|
@ -395,8 +395,8 @@ interface A92 {
|
|||
}
|
||||
|
||||
var a9e = someGenerics9 `${ undefined }${ { x: 6, z: new Date() } }${ { x: 6, y: '' } }`;
|
||||
>a9e : any
|
||||
>someGenerics9 `${ undefined }${ { x: 6, z: new Date() } }${ { x: 6, y: '' } }` : any
|
||||
>a9e : { x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }
|
||||
>someGenerics9 `${ undefined }${ { x: 6, z: new Date() } }${ { x: 6, y: '' } }` : { x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }
|
||||
>someGenerics9 : <T>(strs: TemplateStringsArray, a: T, b: T, c: T) => T
|
||||
>`${ undefined }${ { x: 6, z: new Date() } }${ { x: 6, y: '' } }` : string
|
||||
>undefined : undefined
|
||||
|
@ -413,7 +413,7 @@ var a9e = someGenerics9 `${ undefined }${ { x: 6, z: new Date() } }${ { x: 6, y:
|
|||
>'' : ""
|
||||
|
||||
var a9e: {};
|
||||
>a9e : any
|
||||
>a9e : { x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }
|
||||
|
||||
// Generic tag with multiple parameters of generic type passed arguments with a single best common type
|
||||
var a9d = someGenerics9 `${ { x: 3 }}${ { x: 6 }}${ { x: 6 } }`;
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
tests/cases/compiler/typeArgInference2.ts(12,52): error TS2345: Argument of type '{ name: string; b: number; }' is not assignable to parameter of type '{ name: string; a: number; }'.
|
||||
Object literal may only specify known properties, and 'b' does not exist in type '{ name: string; a: number; }'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/typeArgInference2.ts (1 errors) ====
|
||||
interface Item {
|
||||
name: string;
|
||||
}
|
||||
|
||||
declare function foo<T extends Item>(x?: T, y?: T): T;
|
||||
|
||||
var z1 = foo(null); // any
|
||||
var z2 = foo(); // Item
|
||||
var z3 = foo({ name: null }); // { name: any }
|
||||
var z4 = foo({ name: "abc" }); // { name: string }
|
||||
var z5 = foo({ name: "abc", a: 5 }); // { name: string; a: number }
|
||||
var z6 = foo({ name: "abc", a: 5 }, { name: "def", b: 5 }); // error
|
||||
~~~~
|
||||
!!! error TS2345: Argument of type '{ name: string; b: number; }' is not assignable to parameter of type '{ name: string; a: number; }'.
|
||||
!!! error TS2345: Object literal may only specify known properties, and 'b' does not exist in type '{ name: string; a: number; }'.
|
|
@ -54,8 +54,8 @@ var z5 = foo({ name: "abc", a: 5 }); // { name: string; a: number }
|
|||
>5 : 5
|
||||
|
||||
var z6 = foo({ name: "abc", a: 5 }, { name: "def", b: 5 }); // error
|
||||
>z6 : any
|
||||
>foo({ name: "abc", a: 5 }, { name: "def", b: 5 }) : any
|
||||
>z6 : { name: string; a: number; b?: undefined; } | { name: string; b: number; a?: undefined; }
|
||||
>foo({ name: "abc", a: 5 }, { name: "def", b: 5 }) : { name: string; a: number; b?: undefined; } | { name: string; b: number; a?: undefined; }
|
||||
>foo : <T extends Item>(x?: T, y?: T) => T
|
||||
>{ name: "abc", a: 5 } : { name: string; a: number; }
|
||||
>name : string
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
tests/cases/conformance/expressions/functionCalls/typeArgumentInference.ts(68,29): error TS2345: Argument of type '0' is not assignable to parameter of type '""'.
|
||||
tests/cases/conformance/expressions/functionCalls/typeArgumentInference.ts(82,69): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: Date; }'.
|
||||
Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: Date; }'.
|
||||
tests/cases/conformance/expressions/functionCalls/typeArgumentInference.ts(83,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' has type '{ x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }' at tests/cases/conformance/expressions/functionCalls/typeArgumentInference.ts 81:4, but here has type '{}'.
|
||||
tests/cases/conformance/expressions/functionCalls/typeArgumentInference.ts(84,74): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type 'A92'.
|
||||
Object literal may only specify known properties, and 'y' does not exist in type 'A92'.
|
||||
|
||||
|
@ -90,10 +89,9 @@ tests/cases/conformance/expressions/functionCalls/typeArgumentInference.ts(84,74
|
|||
z?: Date;
|
||||
}
|
||||
var a9e = someGenerics9(undefined, { x: 6, z: new Date() }, { x: 6, y: '' });
|
||||
~~~~~
|
||||
!!! error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: Date; }'.
|
||||
!!! error TS2345: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: Date; }'.
|
||||
var a9e: {};
|
||||
~~~
|
||||
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' has type '{ x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }' at tests/cases/conformance/expressions/functionCalls/typeArgumentInference.ts 81:4, but here has type '{}'.
|
||||
var a9f = someGenerics9<A92>(undefined, { x: 6, z: new Date() }, { x: 6, y: '' });
|
||||
~~~~~
|
||||
!!! error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type 'A92'.
|
||||
|
|
|
@ -421,8 +421,8 @@ interface A92 {
|
|||
>Date : Date
|
||||
}
|
||||
var a9e = someGenerics9(undefined, { x: 6, z: new Date() }, { x: 6, y: '' });
|
||||
>a9e : any
|
||||
>someGenerics9(undefined, { x: 6, z: new Date() }, { x: 6, y: '' }) : any
|
||||
>a9e : { x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }
|
||||
>someGenerics9(undefined, { x: 6, z: new Date() }, { x: 6, y: '' }) : { x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }
|
||||
>someGenerics9 : <T>(a: T, b: T, c: T) => T
|
||||
>undefined : undefined
|
||||
>{ x: 6, z: new Date() } : { x: number; z: Date; }
|
||||
|
@ -438,7 +438,7 @@ var a9e = someGenerics9(undefined, { x: 6, z: new Date() }, { x: 6, y: '' });
|
|||
>'' : ""
|
||||
|
||||
var a9e: {};
|
||||
>a9e : any
|
||||
>a9e : { x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }
|
||||
|
||||
var a9f = someGenerics9<A92>(undefined, { x: 6, z: new Date() }, { x: 6, y: '' });
|
||||
>a9f : any
|
||||
|
|
|
@ -12,8 +12,7 @@ tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstruct
|
|||
tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstructSignatures.ts(106,33): error TS2345: Argument of type '0' is not assignable to parameter of type '""'.
|
||||
tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstructSignatures.ts(118,9): error TS2304: Cannot find name 'Window'.
|
||||
tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstructSignatures.ts(120,51): error TS2304: Cannot find name 'window'.
|
||||
tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstructSignatures.ts(120,69): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: any; }'.
|
||||
Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: any; }'.
|
||||
tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstructSignatures.ts(121,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' has type '{ x: number; z: any; y?: undefined; } | { x: number; y: string; z?: undefined; }' at tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstructSignatures.ts 119:4, but here has type '{}'.
|
||||
tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstructSignatures.ts(122,56): error TS2304: Cannot find name 'window'.
|
||||
tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstructSignatures.ts(122,74): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type 'A92'.
|
||||
Object literal may only specify known properties, and 'y' does not exist in type 'A92'.
|
||||
|
@ -162,10 +161,9 @@ tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstruct
|
|||
var a9e = new someGenerics9(undefined, { x: 6, z: window }, { x: 6, y: '' });
|
||||
~~~~~~
|
||||
!!! error TS2304: Cannot find name 'window'.
|
||||
~~~~~
|
||||
!!! error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: any; }'.
|
||||
!!! error TS2345: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: any; }'.
|
||||
var a9e: {};
|
||||
~~~
|
||||
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' has type '{ x: number; z: any; y?: undefined; } | { x: number; y: string; z?: undefined; }' at tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstructSignatures.ts 119:4, but here has type '{}'.
|
||||
var a9f = new someGenerics9<A92>(undefined, { x: 6, z: window }, { x: 6, y: '' });
|
||||
~~~~~~
|
||||
!!! error TS2304: Cannot find name 'window'.
|
||||
|
|
|
@ -524,8 +524,8 @@ interface A92 {
|
|||
>Window : No type information available!
|
||||
}
|
||||
var a9e = new someGenerics9(undefined, { x: 6, z: window }, { x: 6, y: '' });
|
||||
>a9e : any
|
||||
>new someGenerics9(undefined, { x: 6, z: window }, { x: 6, y: '' }) : any
|
||||
>a9e : { x: number; z: any; y?: undefined; } | { x: number; y: string; z?: undefined; }
|
||||
>new someGenerics9(undefined, { x: 6, z: window }, { x: 6, y: '' }) : { x: number; z: any; y?: undefined; } | { x: number; y: string; z?: undefined; }
|
||||
>someGenerics9 : someGenerics9
|
||||
>undefined : undefined
|
||||
>{ x: 6, z: window } : { x: number; z: any; }
|
||||
|
@ -540,7 +540,7 @@ var a9e = new someGenerics9(undefined, { x: 6, z: window }, { x: 6, y: '' });
|
|||
>'' : ""
|
||||
|
||||
var a9e: {};
|
||||
>a9e : any
|
||||
>a9e : { x: number; z: any; y?: undefined; } | { x: number; y: string; z?: undefined; }
|
||||
|
||||
var a9f = new someGenerics9<A92>(undefined, { x: 6, z: window }, { x: 6, y: '' });
|
||||
>a9f : any
|
||||
|
|
|
@ -17,8 +17,7 @@ tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConst
|
|||
tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConstraints.ts(73,29): error TS2345: Argument of type '0' is not assignable to parameter of type '""'.
|
||||
tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConstraints.ts(85,9): error TS2304: Cannot find name 'Window'.
|
||||
tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConstraints.ts(87,47): error TS2304: Cannot find name 'window'.
|
||||
tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConstraints.ts(87,65): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: any; }'.
|
||||
Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: any; }'.
|
||||
tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConstraints.ts(88,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' has type '{ x: number; z: any; y?: undefined; } | { x: number; y: string; z?: undefined; }' at tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConstraints.ts 86:4, but here has type '{}'.
|
||||
tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConstraints.ts(89,52): error TS2304: Cannot find name 'window'.
|
||||
tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConstraints.ts(89,70): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type 'A92'.
|
||||
Object literal may only specify known properties, and 'y' does not exist in type 'A92'.
|
||||
|
@ -144,10 +143,9 @@ tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConst
|
|||
var a9e = someGenerics9(undefined, { x: 6, z: window }, { x: 6, y: '' });
|
||||
~~~~~~
|
||||
!!! error TS2304: Cannot find name 'window'.
|
||||
~~~~~
|
||||
!!! error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: any; }'.
|
||||
!!! error TS2345: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: any; }'.
|
||||
var a9e: {};
|
||||
~~~
|
||||
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' has type '{ x: number; z: any; y?: undefined; } | { x: number; y: string; z?: undefined; }' at tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConstraints.ts 86:4, but here has type '{}'.
|
||||
var a9f = someGenerics9<A92>(undefined, { x: 6, z: window }, { x: 6, y: '' });
|
||||
~~~~~~
|
||||
!!! error TS2304: Cannot find name 'window'.
|
||||
|
|
|
@ -464,8 +464,8 @@ interface A92 {
|
|||
>Window : No type information available!
|
||||
}
|
||||
var a9e = someGenerics9(undefined, { x: 6, z: window }, { x: 6, y: '' });
|
||||
>a9e : any
|
||||
>someGenerics9(undefined, { x: 6, z: window }, { x: 6, y: '' }) : any
|
||||
>a9e : { x: number; z: any; y?: undefined; } | { x: number; y: string; z?: undefined; }
|
||||
>someGenerics9(undefined, { x: 6, z: window }, { x: 6, y: '' }) : { x: number; z: any; y?: undefined; } | { x: number; y: string; z?: undefined; }
|
||||
>someGenerics9 : <T extends any>(a: T, b: T, c: T) => T
|
||||
>undefined : undefined
|
||||
>{ x: 6, z: window } : { x: number; z: any; }
|
||||
|
@ -480,7 +480,7 @@ var a9e = someGenerics9(undefined, { x: 6, z: window }, { x: 6, y: '' });
|
|||
>'' : ""
|
||||
|
||||
var a9e: {};
|
||||
>a9e : any
|
||||
>a9e : { x: number; z: any; y?: undefined; } | { x: number; y: string; z?: undefined; }
|
||||
|
||||
var a9f = someGenerics9<A92>(undefined, { x: 6, z: window }, { x: 6, y: '' });
|
||||
>a9f : any
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
// @strict: true
|
||||
// @declaration: true
|
||||
|
||||
// Object literals in unions are normalized upon widening
|
||||
let a1 = [{ a: 0 }, { a: 1, b: "x" }, { a: 2, b: "y", c: true }][0];
|
||||
a1.a; // number
|
||||
a1.b; // string | undefined
|
||||
a1.c; // boolean | undefined
|
||||
a1 = { a: 1 };
|
||||
a1 = { a: 0, b: 0 }; // Error
|
||||
a1 = { b: "y" }; // Error
|
||||
a1 = { c: true }; // Error
|
||||
|
||||
let a2 = [{ a: 1, b: 2 }, { a: "abc" }, {}][0];
|
||||
a2.a; // string | number | undefined
|
||||
a2.b; // number | undefined
|
||||
a2 = { a: 10, b: 20 };
|
||||
a2 = { a: "def" };
|
||||
a2 = {};
|
||||
a2 = { a: "def", b: 20 }; // Error
|
||||
a2 = { a: 1 }; // Error
|
||||
|
||||
// Object literals containing spreads are not normalized
|
||||
declare let b1: { a: string, b: string } | { b: string, c: string };
|
||||
let b2 = { ...b1, z: 55 };
|
||||
let b3 = { ...b2 };
|
||||
|
||||
// Before widening {} acts like { [x: string]: undefined }, which is a
|
||||
// subtype of types with all optional properties
|
||||
declare let opts: { foo?: string, bar?: string, baz?: boolean };
|
||||
let c1 = !true ? {} : opts;
|
||||
let c2 = !true ? opts : {};
|
||||
let c3 = !true ? { a: 0, b: 0 } : {};
|
||||
let c4 = !true ? {} : { a: 0, b: 0 };
|
||||
|
||||
// Normalization applies to nested properties
|
||||
let d1 = [{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }][0];
|
||||
d1.kind;
|
||||
d1.pos;
|
||||
d1.pos.x;
|
||||
d1.pos.y;
|
||||
d1.pos.a;
|
||||
d1.pos.b;
|
||||
|
||||
declare function f<T>(...items: T[]): T;
|
||||
declare let data: { a: 1, b: "abc", c: true };
|
||||
|
||||
// Object literals are inferred as a single normalized union type
|
||||
let e1 = f({ a: 1, b: 2 }, { a: "abc" }, {});
|
||||
let e2 = f({}, { a: "abc" }, { a: 1, b: 2 });
|
||||
let e3 = f(data, { a: 2 });
|
||||
let e4 = f({ a: 2 }, data);
|
Loading…
Reference in a new issue