diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e4c2bf2250fb7..4d89ada6d2db0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16918,6 +16918,9 @@ namespace ts { return result; } reportRelationError(headMessage, source, target); + if (source.flags & TypeFlags.TypeVariable && source.symbol?.declarations?.[0] && !getConstraintOfType(source) && isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) { + associateRelatedInfo(createDiagnosticForNode(source.symbol.declarations[0], Diagnostics.This_type_parameter_likely_needs_an_extends_object_constraint)); + } } } } @@ -17468,22 +17471,17 @@ namespace ts { } else { const constraint = getConstraintOfType(source); - if (!constraint || (source.flags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.Any)) { - // A type variable with no constraint is not related to the non-primitive object type. - if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) { + if (constraint) { + // hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed + if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) { + resetErrorInfo(saveErrorInfo); + return result; + } + // slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example + else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, reportErrors, /*headMessage*/ undefined, intersectionState)) { resetErrorInfo(saveErrorInfo); return result; } - } - // hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed - else if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) { - resetErrorInfo(saveErrorInfo); - return result; - } - // slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example - else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, reportErrors, /*headMessage*/ undefined, intersectionState)) { - resetErrorInfo(saveErrorInfo); - return result; } } } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 34873caccb782..d0488f60dadaf 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1532,7 +1532,7 @@ namespace ts { /** * Tests whether a value is an array. */ - export function isArray(value: any): value is readonly {}[] { + export function isArray(value: any): value is readonly unknown[] { return Array.isArray ? Array.isArray(value) : value instanceof Array; } @@ -1565,7 +1565,7 @@ namespace ts { } /** Does nothing. */ - export function noop(_?: {} | null | undefined): void { } + export function noop(_?: unknown): void { } /** Do nothing and return false */ export function returnFalse(): false { return false; } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index cab3de0e1bab0..f4f2f01459a24 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3059,6 +3059,10 @@ "category": "Error", "code": 2796 }, + "This type parameter likely needs an `extends object` constraint.": { + "category": "Error", + "code": 2797 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/src/harness/harnessGlobals.ts b/src/harness/harnessGlobals.ts index 63a85309aaa0a..d7cb5983f90ff 100644 --- a/src/harness/harnessGlobals.ts +++ b/src/harness/harnessGlobals.ts @@ -18,8 +18,8 @@ globalThis.assert = _chai.assert; } assertDeepImpl(a, b, msg); - function arrayExtraKeysObject(a: readonly ({} | null | undefined)[]): object { - const obj: { [key: string]: {} | null | undefined } = {}; + function arrayExtraKeysObject(a: readonly unknown[]): object { + const obj: { [key: string]: unknown } = {}; for (const key in a) { if (Number.isNaN(Number(key))) { obj[key] = a[key]; diff --git a/src/services/shims.ts b/src/services/shims.ts index 14f6a61e7478f..d492c06e3c47b 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -546,7 +546,7 @@ namespace ts { } } - function simpleForwardCall(logger: Logger, actionDescription: string, action: () => {}, logPerformance: boolean): {} { + function simpleForwardCall(logger: Logger, actionDescription: string, action: () => unknown, logPerformance: boolean): unknown { let start: number | undefined; if (logPerformance) { logger.log(actionDescription); diff --git a/tests/baselines/reference/bestCommonTypeOfConditionalExpressions.errors.txt b/tests/baselines/reference/bestCommonTypeOfConditionalExpressions.errors.txt new file mode 100644 index 0000000000000..9153723853d97 --- /dev/null +++ b/tests/baselines/reference/bestCommonTypeOfConditionalExpressions.errors.txt @@ -0,0 +1,35 @@ +tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfConditionalExpressions.ts(25,5): error TS2322: Type 'T | U' is not assignable to type 'Object'. + Type 'T' is not assignable to type 'Object'. + + +==== tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfConditionalExpressions.ts (1 errors) ==== + // conditional expressions return the best common type of the branches plus contextual type (using the first candidate if multiple BCTs exist) + // no errors expected here + + var a: { x: number; y?: number }; + var b: { x: number; z?: number }; + + class Base { foo: string; } + class Derived extends Base { bar: string; } + class Derived2 extends Base { baz: string; } + var base: Base; + var derived: Derived; + var derived2: Derived2; + + var r = true ? 1 : 2; + var r3 = true ? 1 : {}; + var r4 = true ? a : b; // typeof a + var r5 = true ? b : a; // typeof b + var r6 = true ? (x: number) => { } : (x: Object) => { }; // returns number => void + var r7: (x: Object) => void = true ? (x: number) => { } : (x: Object) => { }; + var r8 = true ? (x: Object) => { } : (x: number) => { }; // returns Object => void + var r10: Base = true ? derived : derived2; // no error since we use the contextual type in BCT + var r11 = true ? base : derived2; + + function foo5(t: T, u: U): Object { + return true ? t : u; // BCT is Object + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'T | U' is not assignable to type 'Object'. +!!! error TS2322: Type 'T' is not assignable to type 'Object'. +!!! related TS2797 tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfConditionalExpressions.ts:24:15: This type parameter likely needs an `extends object` constraint. + } \ No newline at end of file diff --git a/tests/baselines/reference/comparisonOperatorWithTypeParameter.errors.txt b/tests/baselines/reference/comparisonOperatorWithTypeParameter.errors.txt index 6b07a7e23640d..c3906738a2f0f 100644 --- a/tests/baselines/reference/comparisonOperatorWithTypeParameter.errors.txt +++ b/tests/baselines/reference/comparisonOperatorWithTypeParameter.errors.txt @@ -30,9 +30,41 @@ tests/cases/conformance/expressions/binaryOperators/comparisonOperator/compariso tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(38,15): error TS2367: This condition will always return 'true' since the types 'V' and 'T' have no overlap. tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(39,15): error TS2367: This condition will always return 'false' since the types 'V' and 'T' have no overlap. tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(40,15): error TS2367: This condition will always return 'true' since the types 'V' and 'T' have no overlap. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(43,15): error TS2365: Operator '<' cannot be applied to types 'T' and '{}'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(44,15): error TS2365: Operator '>' cannot be applied to types 'T' and '{}'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(45,15): error TS2365: Operator '<=' cannot be applied to types 'T' and '{}'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(46,15): error TS2365: Operator '>=' cannot be applied to types 'T' and '{}'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(47,15): error TS2367: This condition will always return 'false' since the types 'T' and '{}' have no overlap. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(48,15): error TS2367: This condition will always return 'true' since the types 'T' and '{}' have no overlap. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(49,15): error TS2367: This condition will always return 'false' since the types 'T' and '{}' have no overlap. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(50,15): error TS2367: This condition will always return 'true' since the types 'T' and '{}' have no overlap. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(52,15): error TS2365: Operator '<' cannot be applied to types '{}' and 'T'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(53,15): error TS2365: Operator '>' cannot be applied to types '{}' and 'T'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(54,15): error TS2365: Operator '<=' cannot be applied to types '{}' and 'T'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(55,15): error TS2365: Operator '>=' cannot be applied to types '{}' and 'T'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(56,15): error TS2367: This condition will always return 'false' since the types '{}' and 'T' have no overlap. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(57,15): error TS2367: This condition will always return 'true' since the types '{}' and 'T' have no overlap. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(58,15): error TS2367: This condition will always return 'false' since the types '{}' and 'T' have no overlap. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(59,15): error TS2367: This condition will always return 'true' since the types '{}' and 'T' have no overlap. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(61,15): error TS2365: Operator '<' cannot be applied to types 'T' and 'Object'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(62,15): error TS2365: Operator '>' cannot be applied to types 'T' and 'Object'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(63,15): error TS2365: Operator '<=' cannot be applied to types 'T' and 'Object'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(64,15): error TS2365: Operator '>=' cannot be applied to types 'T' and 'Object'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(65,15): error TS2367: This condition will always return 'false' since the types 'T' and 'Object' have no overlap. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(66,15): error TS2367: This condition will always return 'true' since the types 'T' and 'Object' have no overlap. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(67,15): error TS2367: This condition will always return 'false' since the types 'T' and 'Object' have no overlap. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(68,15): error TS2367: This condition will always return 'true' since the types 'T' and 'Object' have no overlap. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(70,15): error TS2365: Operator '<' cannot be applied to types 'Object' and 'T'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(71,15): error TS2365: Operator '>' cannot be applied to types 'Object' and 'T'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(72,15): error TS2365: Operator '<=' cannot be applied to types 'Object' and 'T'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(73,15): error TS2365: Operator '>=' cannot be applied to types 'Object' and 'T'. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(74,15): error TS2367: This condition will always return 'false' since the types 'Object' and 'T' have no overlap. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(75,15): error TS2367: This condition will always return 'true' since the types 'Object' and 'T' have no overlap. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(76,15): error TS2367: This condition will always return 'false' since the types 'Object' and 'T' have no overlap. +tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts(77,15): error TS2367: This condition will always return 'true' since the types 'Object' and 'T' have no overlap. -==== tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts (32 errors) ==== +==== tests/cases/conformance/expressions/binaryOperators/comparisonOperator/comparisonOperatorWithTypeParameter.ts (64 errors) ==== var a: {}; var b: Object; @@ -140,38 +172,102 @@ tests/cases/conformance/expressions/binaryOperators/comparisonOperator/compariso // ok var re1 = t < a; + ~~~~~ +!!! error TS2365: Operator '<' cannot be applied to types 'T' and '{}'. var re2 = t > a; + ~~~~~ +!!! error TS2365: Operator '>' cannot be applied to types 'T' and '{}'. var re3 = t <= a; + ~~~~~~ +!!! error TS2365: Operator '<=' cannot be applied to types 'T' and '{}'. var re4 = t >= a; + ~~~~~~ +!!! error TS2365: Operator '>=' cannot be applied to types 'T' and '{}'. var re5 = t == a; + ~~~~~~ +!!! error TS2367: This condition will always return 'false' since the types 'T' and '{}' have no overlap. var re6 = t != a; + ~~~~~~ +!!! error TS2367: This condition will always return 'true' since the types 'T' and '{}' have no overlap. var re7 = t === a; + ~~~~~~~ +!!! error TS2367: This condition will always return 'false' since the types 'T' and '{}' have no overlap. var re8 = t !== a; + ~~~~~~~ +!!! error TS2367: This condition will always return 'true' since the types 'T' and '{}' have no overlap. var rf1 = a < t; + ~~~~~ +!!! error TS2365: Operator '<' cannot be applied to types '{}' and 'T'. var rf2 = a > t; + ~~~~~ +!!! error TS2365: Operator '>' cannot be applied to types '{}' and 'T'. var rf3 = a <= t; + ~~~~~~ +!!! error TS2365: Operator '<=' cannot be applied to types '{}' and 'T'. var rf4 = a >= t; + ~~~~~~ +!!! error TS2365: Operator '>=' cannot be applied to types '{}' and 'T'. var rf5 = a == t; + ~~~~~~ +!!! error TS2367: This condition will always return 'false' since the types '{}' and 'T' have no overlap. var rf6 = a != t; + ~~~~~~ +!!! error TS2367: This condition will always return 'true' since the types '{}' and 'T' have no overlap. var rf7 = a === t; + ~~~~~~~ +!!! error TS2367: This condition will always return 'false' since the types '{}' and 'T' have no overlap. var rf8 = a !== t; + ~~~~~~~ +!!! error TS2367: This condition will always return 'true' since the types '{}' and 'T' have no overlap. var rg1 = t < b; + ~~~~~ +!!! error TS2365: Operator '<' cannot be applied to types 'T' and 'Object'. var rg2 = t > b; + ~~~~~ +!!! error TS2365: Operator '>' cannot be applied to types 'T' and 'Object'. var rg3 = t <= b; + ~~~~~~ +!!! error TS2365: Operator '<=' cannot be applied to types 'T' and 'Object'. var rg4 = t >= b; + ~~~~~~ +!!! error TS2365: Operator '>=' cannot be applied to types 'T' and 'Object'. var rg5 = t == b; + ~~~~~~ +!!! error TS2367: This condition will always return 'false' since the types 'T' and 'Object' have no overlap. var rg6 = t != b; + ~~~~~~ +!!! error TS2367: This condition will always return 'true' since the types 'T' and 'Object' have no overlap. var rg7 = t === b; + ~~~~~~~ +!!! error TS2367: This condition will always return 'false' since the types 'T' and 'Object' have no overlap. var rg8 = t !== b; + ~~~~~~~ +!!! error TS2367: This condition will always return 'true' since the types 'T' and 'Object' have no overlap. var rh1 = b < t; + ~~~~~ +!!! error TS2365: Operator '<' cannot be applied to types 'Object' and 'T'. var rh2 = b > t; + ~~~~~ +!!! error TS2365: Operator '>' cannot be applied to types 'Object' and 'T'. var rh3 = b <= t; + ~~~~~~ +!!! error TS2365: Operator '<=' cannot be applied to types 'Object' and 'T'. var rh4 = b >= t; + ~~~~~~ +!!! error TS2365: Operator '>=' cannot be applied to types 'Object' and 'T'. var rh5 = b == t; + ~~~~~~ +!!! error TS2367: This condition will always return 'false' since the types 'Object' and 'T' have no overlap. var rh6 = b != t; + ~~~~~~ +!!! error TS2367: This condition will always return 'true' since the types 'Object' and 'T' have no overlap. var rh7 = b === t; + ~~~~~~~ +!!! error TS2367: This condition will always return 'false' since the types 'Object' and 'T' have no overlap. var rh8 = b !== t; + ~~~~~~~ +!!! error TS2367: This condition will always return 'true' since the types 'Object' and 'T' have no overlap. } \ No newline at end of file diff --git a/tests/baselines/reference/complexRecursiveCollections.errors.txt b/tests/baselines/reference/complexRecursiveCollections.errors.txt index 91745b84e384d..73f1a988bfe1b 100644 --- a/tests/baselines/reference/complexRecursiveCollections.errors.txt +++ b/tests/baselines/reference/complexRecursiveCollections.errors.txt @@ -1,3 +1,4 @@ +tests/cases/compiler/immutable.ts(261,76): error TS2344: Type 'T' does not satisfy the constraint 'Object'. tests/cases/compiler/immutable.ts(341,22): error TS2430: Interface 'Keyed' incorrectly extends interface 'Collection'. The types returned by 'toSeq()' are incompatible between these types. Type 'Keyed' is not assignable to type 'this'. @@ -33,7 +34,7 @@ tests/cases/compiler/immutable.ts(391,22): error TS2430: Interface 'Set' inco flatMap(mapper: (value: T, key: void, iter: this) => Ara, context?: any): N2; toSeq(): N2; } -==== tests/cases/compiler/immutable.ts (3 errors) ==== +==== tests/cases/compiler/immutable.ts (4 errors) ==== // Test that complex recursive collections can pass the `extends` assignability check without // running out of memory. This bug was exposed in Typescript 2.4 when more generic signatures // started being checked. @@ -295,6 +296,9 @@ tests/cases/compiler/immutable.ts(391,22): error TS2430: Interface 'Set' inco } } export function Record(defaultValues: T, name?: string): Record.Class; + ~ +!!! error TS2344: Type 'T' does not satisfy the constraint 'Object'. +!!! related TS2797 tests/cases/compiler/immutable.ts:261:26: This type parameter likely needs an `extends object` constraint. export module Seq { function isSeq(maybeSeq: any): maybeSeq is Seq.Indexed | Seq.Keyed; function of(...values: Array): Seq.Indexed; diff --git a/tests/baselines/reference/conditionalTypeDoesntSpinForever.js b/tests/baselines/reference/conditionalTypeDoesntSpinForever.js index 144503ac94bbe..2943943b4a6e4 100644 --- a/tests/baselines/reference/conditionalTypeDoesntSpinForever.js +++ b/tests/baselines/reference/conditionalTypeDoesntSpinForever.js @@ -15,25 +15,25 @@ export enum PubSubRecordIsStoredInRedisAsA { maxMsToWaitBeforePublishing: number; } - type NameFieldConstructor = + type NameFieldConstructor = SO_FAR extends {name: any} ? {} : { name: (t?: TYPE) => BuildPubSubRecordType } - const buildNameFieldConstructor = (soFar: SO_FAR) => ( + const buildNameFieldConstructor = (soFar: SO_FAR) => ( "name" in soFar ? {} : { name: (instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) as BuildPubSubRecordType } ); - type StoredAsConstructor = + type StoredAsConstructor = SO_FAR extends {storedAs: any} ? {} : { storedAsJsonEncodedRedisString: () => BuildPubSubRecordType; storedRedisHash: () => BuildPubSubRecordType; } - const buildStoredAsConstructor = (soFar: SO_FAR) => ( + const buildStoredAsConstructor = (soFar: SO_FAR) => ( "storedAs" in soFar ? {} : { storedAsJsonEncodedRedisString: () => buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as @@ -44,38 +44,38 @@ export enum PubSubRecordIsStoredInRedisAsA { } ); - type IdentifierFieldConstructor = + type IdentifierFieldConstructor = SO_FAR extends {identifier: any} ? {} : SO_FAR extends {record: any} ? { identifier: >(t?: TYPE) => BuildPubSubRecordType } : {} - const buildIdentifierFieldConstructor = (soFar: SO_FAR) => ( + const buildIdentifierFieldConstructor = (soFar: SO_FAR) => ( "identifier" in soFar || (!("record" in soFar)) ? {} : { identifier: (instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) as BuildPubSubRecordType } ); - type RecordFieldConstructor = + type RecordFieldConstructor = SO_FAR extends {record: any} ? {} : { record: (t?: TYPE) => BuildPubSubRecordType } - const buildRecordFieldConstructor = (soFar: SO_FAR) => ( + const buildRecordFieldConstructor = (soFar: SO_FAR) => ( "record" in soFar ? {} : { record: (instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) as BuildPubSubRecordType } ); - type MaxMsToWaitBeforePublishingFieldConstructor = + type MaxMsToWaitBeforePublishingFieldConstructor = SO_FAR extends {maxMsToWaitBeforePublishing: any} ? {} : { maxMsToWaitBeforePublishing: (t: number) => BuildPubSubRecordType, neverDelayPublishing: () => BuildPubSubRecordType, } - const buildMaxMsToWaitBeforePublishingFieldConstructor = (soFar: SO_FAR): MaxMsToWaitBeforePublishingFieldConstructor => ( + const buildMaxMsToWaitBeforePublishingFieldConstructor = (soFar: SO_FAR): MaxMsToWaitBeforePublishingFieldConstructor => ( "maxMsToWaitBeforePublishing" in soFar ? {} : { maxMsToWaitBeforePublishing: (instance: number = 0) => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType, @@ -84,14 +84,14 @@ export enum PubSubRecordIsStoredInRedisAsA { } ) as MaxMsToWaitBeforePublishingFieldConstructor; - type TypeConstructor = + type TypeConstructor = SO_FAR extends {identifier: any, record: any, maxMsToWaitBeforePublishing: number, storedAs: PubSubRecordIsStoredInRedisAsA} ? { type: SO_FAR, fields: Set, hasField: (fieldName: string | number | symbol) => fieldName is keyof SO_FAR } : {} - const buildType = (soFar: SO_FAR) => ( + const buildType = (soFar: SO_FAR) => ( "identifier" in soFar && "object" in soFar && "maxMsToWaitBeforePublishing" in soFar && "PubSubRecordIsStoredInRedisAsA" in soFar ? {} : { type: soFar, fields: () => new Set(Object.keys(soFar) as (keyof SO_FAR)[]), @@ -99,7 +99,7 @@ export enum PubSubRecordIsStoredInRedisAsA { } ); - type BuildPubSubRecordType = + type BuildPubSubRecordType = NameFieldConstructor & IdentifierFieldConstructor & RecordFieldConstructor & @@ -107,7 +107,7 @@ export enum PubSubRecordIsStoredInRedisAsA { MaxMsToWaitBeforePublishingFieldConstructor & TypeConstructor - const buildPubSubRecordType = (soFar: SO_FAR) => Object.assign( + const buildPubSubRecordType = (soFar: SO_FAR) => Object.assign( {}, buildNameFieldConstructor(soFar), buildIdentifierFieldConstructor(soFar), diff --git a/tests/baselines/reference/conditionalTypeDoesntSpinForever.symbols b/tests/baselines/reference/conditionalTypeDoesntSpinForever.symbols index b5dcb78015b3f..c476abe113a0f 100644 --- a/tests/baselines/reference/conditionalTypeDoesntSpinForever.symbols +++ b/tests/baselines/reference/conditionalTypeDoesntSpinForever.symbols @@ -40,7 +40,7 @@ export enum PubSubRecordIsStoredInRedisAsA { >maxMsToWaitBeforePublishing : Symbol(PubSubRecord.maxMsToWaitBeforePublishing, Decl(conditionalTypeDoesntSpinForever.ts, 12, 45)) } - type NameFieldConstructor = + type NameFieldConstructor = >NameFieldConstructor : Symbol(NameFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 14, 3)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 16, 28)) @@ -59,14 +59,14 @@ export enum PubSubRecordIsStoredInRedisAsA { >TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 18, 13)) } - const buildNameFieldConstructor = (soFar: SO_FAR) => ( + const buildNameFieldConstructor = (soFar: SO_FAR) => ( >buildNameFieldConstructor : Symbol(buildNameFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 21, 7)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 21, 37)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 21, 45)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 21, 60)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 21, 37)) "name" in soFar ? {} : { ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 21, 45)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 21, 60)) name: (instance: TYPE = undefined) => >name : Symbol(name, Decl(conditionalTypeDoesntSpinForever.ts, 22, 28)) @@ -80,7 +80,7 @@ export enum PubSubRecordIsStoredInRedisAsA { >Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 21, 45)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 21, 60)) >name : Symbol(name, Decl(conditionalTypeDoesntSpinForever.ts, 24, 56)) >instance : Symbol(instance, Decl(conditionalTypeDoesntSpinForever.ts, 23, 19)) >TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 23, 13)) @@ -94,7 +94,7 @@ export enum PubSubRecordIsStoredInRedisAsA { } ); - type StoredAsConstructor = + type StoredAsConstructor = >StoredAsConstructor : Symbol(StoredAsConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 26, 4)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 28, 27)) @@ -119,14 +119,14 @@ export enum PubSubRecordIsStoredInRedisAsA { >redisHash : Symbol(PubSubRecordIsStoredInRedisAsA.redisHash, Decl(conditionalTypeDoesntSpinForever.ts, 3, 44)) } - const buildStoredAsConstructor = (soFar: SO_FAR) => ( + const buildStoredAsConstructor = (soFar: SO_FAR) => ( >buildStoredAsConstructor : Symbol(buildStoredAsConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 34, 7)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 34, 36)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 34, 44)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 34, 59)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 34, 36)) "storedAs" in soFar ? {} : { ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 34, 44)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 34, 59)) storedAsJsonEncodedRedisString: () => >storedAsJsonEncodedRedisString : Symbol(storedAsJsonEncodedRedisString, Decl(conditionalTypeDoesntSpinForever.ts, 35, 32)) @@ -136,7 +136,7 @@ export enum PubSubRecordIsStoredInRedisAsA { >Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 34, 44)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 34, 59)) >storedAs : Symbol(storedAs, Decl(conditionalTypeDoesntSpinForever.ts, 37, 56)) >PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString : Symbol(PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString, Decl(conditionalTypeDoesntSpinForever.ts, 4, 28)) >PubSubRecordIsStoredInRedisAsA : Symbol(PubSubRecordIsStoredInRedisAsA, Decl(conditionalTypeDoesntSpinForever.ts, 0, 0)) @@ -157,7 +157,7 @@ export enum PubSubRecordIsStoredInRedisAsA { >Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 34, 44)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 34, 59)) >storedAs : Symbol(storedAs, Decl(conditionalTypeDoesntSpinForever.ts, 40, 56)) >PubSubRecordIsStoredInRedisAsA.redisHash : Symbol(PubSubRecordIsStoredInRedisAsA.redisHash, Decl(conditionalTypeDoesntSpinForever.ts, 3, 44)) >PubSubRecordIsStoredInRedisAsA : Symbol(PubSubRecordIsStoredInRedisAsA, Decl(conditionalTypeDoesntSpinForever.ts, 0, 0)) @@ -172,7 +172,7 @@ export enum PubSubRecordIsStoredInRedisAsA { } ); - type IdentifierFieldConstructor = + type IdentifierFieldConstructor = >IdentifierFieldConstructor : Symbol(IdentifierFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 43, 4)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 45, 34)) @@ -198,15 +198,15 @@ export enum PubSubRecordIsStoredInRedisAsA { } : {} - const buildIdentifierFieldConstructor = (soFar: SO_FAR) => ( + const buildIdentifierFieldConstructor = (soFar: SO_FAR) => ( >buildIdentifierFieldConstructor : Symbol(buildIdentifierFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 51, 7)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 51, 43)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 51, 51)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 51, 66)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 51, 43)) "identifier" in soFar || (!("record" in soFar)) ? {} : { ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 51, 51)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 51, 51)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 51, 66)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 51, 66)) identifier: (instance: TYPE = undefined) => >identifier : Symbol(identifier, Decl(conditionalTypeDoesntSpinForever.ts, 52, 60)) @@ -220,7 +220,7 @@ export enum PubSubRecordIsStoredInRedisAsA { >Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 51, 51)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 51, 66)) >identifier : Symbol(identifier, Decl(conditionalTypeDoesntSpinForever.ts, 54, 56)) >instance : Symbol(instance, Decl(conditionalTypeDoesntSpinForever.ts, 53, 25)) >TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 53, 19)) @@ -234,7 +234,7 @@ export enum PubSubRecordIsStoredInRedisAsA { } ); - type RecordFieldConstructor = + type RecordFieldConstructor = >RecordFieldConstructor : Symbol(RecordFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 56, 4)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 58, 30)) @@ -253,14 +253,14 @@ export enum PubSubRecordIsStoredInRedisAsA { >TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 60, 15)) } - const buildRecordFieldConstructor = (soFar: SO_FAR) => ( + const buildRecordFieldConstructor = (soFar: SO_FAR) => ( >buildRecordFieldConstructor : Symbol(buildRecordFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 63, 7)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 63, 39)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 63, 47)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 63, 62)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 63, 39)) "record" in soFar ? {} : { ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 63, 47)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 63, 62)) record: (instance: TYPE = undefined) => >record : Symbol(record, Decl(conditionalTypeDoesntSpinForever.ts, 64, 30)) @@ -274,7 +274,7 @@ export enum PubSubRecordIsStoredInRedisAsA { >Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 63, 47)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 63, 62)) >record : Symbol(record, Decl(conditionalTypeDoesntSpinForever.ts, 66, 56)) >instance : Symbol(instance, Decl(conditionalTypeDoesntSpinForever.ts, 65, 21)) >TYPE : Symbol(TYPE, Decl(conditionalTypeDoesntSpinForever.ts, 65, 15)) @@ -288,7 +288,7 @@ export enum PubSubRecordIsStoredInRedisAsA { } ); - type MaxMsToWaitBeforePublishingFieldConstructor = + type MaxMsToWaitBeforePublishingFieldConstructor = >MaxMsToWaitBeforePublishingFieldConstructor : Symbol(MaxMsToWaitBeforePublishingFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 68, 4)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 70, 51)) @@ -310,16 +310,16 @@ export enum PubSubRecordIsStoredInRedisAsA { >maxMsToWaitBeforePublishing : Symbol(maxMsToWaitBeforePublishing, Decl(conditionalTypeDoesntSpinForever.ts, 73, 66)) } - const buildMaxMsToWaitBeforePublishingFieldConstructor = (soFar: SO_FAR): MaxMsToWaitBeforePublishingFieldConstructor => ( + const buildMaxMsToWaitBeforePublishingFieldConstructor = (soFar: SO_FAR): MaxMsToWaitBeforePublishingFieldConstructor => ( >buildMaxMsToWaitBeforePublishingFieldConstructor : Symbol(buildMaxMsToWaitBeforePublishingFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 76, 7)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 76, 60)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 76, 68)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 76, 83)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 76, 60)) >MaxMsToWaitBeforePublishingFieldConstructor : Symbol(MaxMsToWaitBeforePublishingFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 68, 4)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 76, 60)) "maxMsToWaitBeforePublishing" in soFar ? {} : { ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 76, 68)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 76, 83)) maxMsToWaitBeforePublishing: (instance: number = 0) => >maxMsToWaitBeforePublishing : Symbol(maxMsToWaitBeforePublishing, Decl(conditionalTypeDoesntSpinForever.ts, 77, 51)) @@ -330,7 +330,7 @@ export enum PubSubRecordIsStoredInRedisAsA { >Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 76, 68)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 76, 83)) >maxMsToWaitBeforePublishing : Symbol(maxMsToWaitBeforePublishing, Decl(conditionalTypeDoesntSpinForever.ts, 79, 56)) >instance : Symbol(instance, Decl(conditionalTypeDoesntSpinForever.ts, 78, 36)) >BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4)) @@ -345,7 +345,7 @@ export enum PubSubRecordIsStoredInRedisAsA { >Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 76, 68)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 76, 83)) >maxMsToWaitBeforePublishing : Symbol(maxMsToWaitBeforePublishing, Decl(conditionalTypeDoesntSpinForever.ts, 81, 56)) >BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 76, 60)) @@ -355,7 +355,7 @@ export enum PubSubRecordIsStoredInRedisAsA { >MaxMsToWaitBeforePublishingFieldConstructor : Symbol(MaxMsToWaitBeforePublishingFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 68, 4)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 76, 60)) - type TypeConstructor = + type TypeConstructor = >TypeConstructor : Symbol(TypeConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 83, 59)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 85, 23)) @@ -384,21 +384,21 @@ export enum PubSubRecordIsStoredInRedisAsA { } : {} - const buildType = (soFar: SO_FAR) => ( + const buildType = (soFar: SO_FAR) => ( >buildType : Symbol(buildType, Decl(conditionalTypeDoesntSpinForever.ts, 92, 7)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 92, 21)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 29)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 44)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 92, 21)) "identifier" in soFar && "object" in soFar && "maxMsToWaitBeforePublishing" in soFar && "PubSubRecordIsStoredInRedisAsA" in soFar ? {} : { ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 29)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 29)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 29)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 29)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 44)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 44)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 44)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 44)) type: soFar, >type : Symbol(type, Decl(conditionalTypeDoesntSpinForever.ts, 93, 142)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 29)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 44)) fields: () => new Set(Object.keys(soFar) as (keyof SO_FAR)[]), >fields : Symbol(fields, Decl(conditionalTypeDoesntSpinForever.ts, 94, 18)) @@ -406,18 +406,18 @@ export enum PubSubRecordIsStoredInRedisAsA { >Object.keys : Symbol(ObjectConstructor.keys, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >keys : Symbol(ObjectConstructor.keys, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 29)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 44)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 92, 21)) hasField: (fieldName: string | number | symbol) => fieldName in soFar >hasField : Symbol(hasField, Decl(conditionalTypeDoesntSpinForever.ts, 95, 68)) >fieldName : Symbol(fieldName, Decl(conditionalTypeDoesntSpinForever.ts, 96, 17)) >fieldName : Symbol(fieldName, Decl(conditionalTypeDoesntSpinForever.ts, 96, 17)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 29)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 92, 44)) } ); - type BuildPubSubRecordType = + type BuildPubSubRecordType = >BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 100, 29)) @@ -445,10 +445,10 @@ export enum PubSubRecordIsStoredInRedisAsA { >TypeConstructor : Symbol(TypeConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 83, 59)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 100, 29)) - const buildPubSubRecordType = (soFar: SO_FAR) => Object.assign( + const buildPubSubRecordType = (soFar: SO_FAR) => Object.assign( >buildPubSubRecordType : Symbol(buildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 108, 7)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 108, 33)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 41)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 56)) >SO_FAR : Symbol(SO_FAR, Decl(conditionalTypeDoesntSpinForever.ts, 108, 33)) >Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) @@ -457,27 +457,27 @@ export enum PubSubRecordIsStoredInRedisAsA { {}, buildNameFieldConstructor(soFar), >buildNameFieldConstructor : Symbol(buildNameFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 21, 7)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 41)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 56)) buildIdentifierFieldConstructor(soFar), >buildIdentifierFieldConstructor : Symbol(buildIdentifierFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 51, 7)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 41)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 56)) buildRecordFieldConstructor(soFar), >buildRecordFieldConstructor : Symbol(buildRecordFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 63, 7)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 41)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 56)) buildStoredAsConstructor(soFar), >buildStoredAsConstructor : Symbol(buildStoredAsConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 34, 7)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 41)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 56)) buildMaxMsToWaitBeforePublishingFieldConstructor(soFar), >buildMaxMsToWaitBeforePublishingFieldConstructor : Symbol(buildMaxMsToWaitBeforePublishingFieldConstructor, Decl(conditionalTypeDoesntSpinForever.ts, 76, 7)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 41)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 56)) buildType(soFar) >buildType : Symbol(buildType, Decl(conditionalTypeDoesntSpinForever.ts, 92, 7)) ->soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 41)) +>soFar : Symbol(soFar, Decl(conditionalTypeDoesntSpinForever.ts, 108, 56)) ) as BuildPubSubRecordType; >BuildPubSubRecordType : Symbol(BuildPubSubRecordType, Decl(conditionalTypeDoesntSpinForever.ts, 98, 4)) diff --git a/tests/baselines/reference/conditionalTypeDoesntSpinForever.types b/tests/baselines/reference/conditionalTypeDoesntSpinForever.types index e60be08b85d4c..5b4967c42d795 100644 --- a/tests/baselines/reference/conditionalTypeDoesntSpinForever.types +++ b/tests/baselines/reference/conditionalTypeDoesntSpinForever.types @@ -31,7 +31,7 @@ export enum PubSubRecordIsStoredInRedisAsA { >maxMsToWaitBeforePublishing : number } - type NameFieldConstructor = + type NameFieldConstructor = >NameFieldConstructor : NameFieldConstructor SO_FAR extends {name: any} ? {} : { @@ -43,9 +43,9 @@ export enum PubSubRecordIsStoredInRedisAsA { >name : TYPE } - const buildNameFieldConstructor = (soFar: SO_FAR) => ( ->buildNameFieldConstructor : (soFar: SO_FAR) => { name?: undefined; } | { name: (instance?: TYPE) => BuildPubSubRecordType; } ->(soFar: SO_FAR) => ( "name" in soFar ? {} : { name: (instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) as BuildPubSubRecordType } ) : (soFar: SO_FAR) => { name?: undefined; } | { name: (instance?: TYPE) => BuildPubSubRecordType; } + const buildNameFieldConstructor = (soFar: SO_FAR) => ( +>buildNameFieldConstructor : (soFar: SO_FAR) => { name?: undefined; } | { name: (instance?: TYPE) => BuildPubSubRecordType; } +>(soFar: SO_FAR) => ( "name" in soFar ? {} : { name: (instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) as BuildPubSubRecordType } ) : (soFar: SO_FAR) => { name?: undefined; } | { name: (instance?: TYPE) => BuildPubSubRecordType; } >soFar : SO_FAR >( "name" in soFar ? {} : { name: (instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) as BuildPubSubRecordType } ) : {} | { name: (instance?: TYPE) => BuildPubSubRecordType; } @@ -66,7 +66,7 @@ export enum PubSubRecordIsStoredInRedisAsA { buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) as BuildPubSubRecordType >buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) as BuildPubSubRecordType : BuildPubSubRecordType >buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) : BuildPubSubRecordType ->buildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType +>buildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType >Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE} : SO_FAR & { name: TYPE; } >Object.assign({}, soFar, {name: instance as TYPE}) : SO_FAR & { name: TYPE; } >Object.assign : { (target: T, source: U): T & U; (target: T, source1: U, source2: V): T & U & V; (target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; } @@ -83,7 +83,7 @@ export enum PubSubRecordIsStoredInRedisAsA { } ); - type StoredAsConstructor = + type StoredAsConstructor = >StoredAsConstructor : StoredAsConstructor SO_FAR extends {storedAs: any} ? {} : { @@ -100,9 +100,9 @@ export enum PubSubRecordIsStoredInRedisAsA { >PubSubRecordIsStoredInRedisAsA : any } - const buildStoredAsConstructor = (soFar: SO_FAR) => ( ->buildStoredAsConstructor : (soFar: SO_FAR) => { storedAsJsonEncodedRedisString?: undefined; storedAsRedisHash?: undefined; } | { storedAsJsonEncodedRedisString: () => BuildPubSubRecordType; storedAsRedisHash: () => BuildPubSubRecordType; } ->(soFar: SO_FAR) => ( "storedAs" in soFar ? {} : { storedAsJsonEncodedRedisString: () => buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as BuildPubSubRecordType, storedAsRedisHash: () => buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) as BuildPubSubRecordType, } ) : (soFar: SO_FAR) => { storedAsJsonEncodedRedisString?: undefined; storedAsRedisHash?: undefined; } | { storedAsJsonEncodedRedisString: () => BuildPubSubRecordType; storedAsRedisHash: () => BuildPubSubRecordType; } + const buildStoredAsConstructor = (soFar: SO_FAR) => ( +>buildStoredAsConstructor : (soFar: SO_FAR) => { storedAsJsonEncodedRedisString?: undefined; storedAsRedisHash?: undefined; } | { storedAsJsonEncodedRedisString: () => BuildPubSubRecordType; storedAsRedisHash: () => BuildPubSubRecordType; } +>(soFar: SO_FAR) => ( "storedAs" in soFar ? {} : { storedAsJsonEncodedRedisString: () => buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as BuildPubSubRecordType, storedAsRedisHash: () => buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) as BuildPubSubRecordType, } ) : (soFar: SO_FAR) => { storedAsJsonEncodedRedisString?: undefined; storedAsRedisHash?: undefined; } | { storedAsJsonEncodedRedisString: () => BuildPubSubRecordType; storedAsRedisHash: () => BuildPubSubRecordType; } >soFar : SO_FAR >( "storedAs" in soFar ? {} : { storedAsJsonEncodedRedisString: () => buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as BuildPubSubRecordType, storedAsRedisHash: () => buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) as BuildPubSubRecordType, } ) : {} | { storedAsJsonEncodedRedisString: () => BuildPubSubRecordType; storedAsRedisHash: () => BuildPubSubRecordType; } @@ -121,7 +121,7 @@ export enum PubSubRecordIsStoredInRedisAsA { buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as >buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as BuildPubSubRecordType : BuildPubSubRecordType >buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) : BuildPubSubRecordType ->buildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType +>buildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType >Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}) : SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA; } >Object.assign : { (target: T, source: U): T & U; (target: T, source1: U, source2: V): T & U & V; (target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; } >Object : ObjectConstructor @@ -145,7 +145,7 @@ export enum PubSubRecordIsStoredInRedisAsA { buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) as >buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) as BuildPubSubRecordType : BuildPubSubRecordType >buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) : BuildPubSubRecordType ->buildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType +>buildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType >Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}) : SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA; } >Object.assign : { (target: T, source: U): T & U; (target: T, source1: U, source2: V): T & U & V; (target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; } >Object : ObjectConstructor @@ -164,7 +164,7 @@ export enum PubSubRecordIsStoredInRedisAsA { } ); - type IdentifierFieldConstructor = + type IdentifierFieldConstructor = >IdentifierFieldConstructor : IdentifierFieldConstructor SO_FAR extends {identifier: any} ? {} : @@ -180,9 +180,9 @@ export enum PubSubRecordIsStoredInRedisAsA { } : {} - const buildIdentifierFieldConstructor = (soFar: SO_FAR) => ( ->buildIdentifierFieldConstructor : (soFar: SO_FAR) => { identifier?: undefined; } | { identifier: (instance?: TYPE) => BuildPubSubRecordType; } ->(soFar: SO_FAR) => ( "identifier" in soFar || (!("record" in soFar)) ? {} : { identifier: (instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) as BuildPubSubRecordType } ) : (soFar: SO_FAR) => { identifier?: undefined; } | { identifier: (instance?: TYPE) => BuildPubSubRecordType; } + const buildIdentifierFieldConstructor = (soFar: SO_FAR) => ( +>buildIdentifierFieldConstructor : (soFar: SO_FAR) => { identifier?: undefined; } | { identifier: (instance?: TYPE) => BuildPubSubRecordType; } +>(soFar: SO_FAR) => ( "identifier" in soFar || (!("record" in soFar)) ? {} : { identifier: (instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) as BuildPubSubRecordType } ) : (soFar: SO_FAR) => { identifier?: undefined; } | { identifier: (instance?: TYPE) => BuildPubSubRecordType; } >soFar : SO_FAR >( "identifier" in soFar || (!("record" in soFar)) ? {} : { identifier: (instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) as BuildPubSubRecordType } ) : {} | { identifier: (instance?: TYPE) => BuildPubSubRecordType; } @@ -210,7 +210,7 @@ export enum PubSubRecordIsStoredInRedisAsA { buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) as BuildPubSubRecordType >buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) as BuildPubSubRecordType : BuildPubSubRecordType >buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) : BuildPubSubRecordType ->buildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType +>buildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType >Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE} : SO_FAR & { identifier: TYPE; } >Object.assign({}, soFar, {identifier: instance as TYPE}) : SO_FAR & { identifier: TYPE; } >Object.assign : { (target: T, source: U): T & U; (target: T, source1: U, source2: V): T & U & V; (target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; } @@ -227,7 +227,7 @@ export enum PubSubRecordIsStoredInRedisAsA { } ); - type RecordFieldConstructor = + type RecordFieldConstructor = >RecordFieldConstructor : RecordFieldConstructor SO_FAR extends {record: any} ? {} : { @@ -239,9 +239,9 @@ export enum PubSubRecordIsStoredInRedisAsA { >record : TYPE } - const buildRecordFieldConstructor = (soFar: SO_FAR) => ( ->buildRecordFieldConstructor : (soFar: SO_FAR) => { record?: undefined; } | { record: (instance?: TYPE) => BuildPubSubRecordType; } ->(soFar: SO_FAR) => ( "record" in soFar ? {} : { record: (instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) as BuildPubSubRecordType } ) : (soFar: SO_FAR) => { record?: undefined; } | { record: (instance?: TYPE) => BuildPubSubRecordType; } + const buildRecordFieldConstructor = (soFar: SO_FAR) => ( +>buildRecordFieldConstructor : (soFar: SO_FAR) => { record?: undefined; } | { record: (instance?: TYPE) => BuildPubSubRecordType; } +>(soFar: SO_FAR) => ( "record" in soFar ? {} : { record: (instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) as BuildPubSubRecordType } ) : (soFar: SO_FAR) => { record?: undefined; } | { record: (instance?: TYPE) => BuildPubSubRecordType; } >soFar : SO_FAR >( "record" in soFar ? {} : { record: (instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) as BuildPubSubRecordType } ) : {} | { record: (instance?: TYPE) => BuildPubSubRecordType; } @@ -262,7 +262,7 @@ export enum PubSubRecordIsStoredInRedisAsA { buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) as BuildPubSubRecordType >buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) as BuildPubSubRecordType : BuildPubSubRecordType >buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) : BuildPubSubRecordType ->buildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType +>buildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType >Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE} : SO_FAR & { record: TYPE; } >Object.assign({}, soFar, {record: instance as TYPE}) : SO_FAR & { record: TYPE; } >Object.assign : { (target: T, source: U): T & U; (target: T, source1: U, source2: V): T & U & V; (target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; } @@ -279,7 +279,7 @@ export enum PubSubRecordIsStoredInRedisAsA { } ); - type MaxMsToWaitBeforePublishingFieldConstructor = + type MaxMsToWaitBeforePublishingFieldConstructor = >MaxMsToWaitBeforePublishingFieldConstructor : MaxMsToWaitBeforePublishingFieldConstructor SO_FAR extends {maxMsToWaitBeforePublishing: any} ? {} : { @@ -295,9 +295,9 @@ export enum PubSubRecordIsStoredInRedisAsA { >maxMsToWaitBeforePublishing : 0 } - const buildMaxMsToWaitBeforePublishingFieldConstructor = (soFar: SO_FAR): MaxMsToWaitBeforePublishingFieldConstructor => ( ->buildMaxMsToWaitBeforePublishingFieldConstructor : (soFar: SO_FAR) => MaxMsToWaitBeforePublishingFieldConstructor ->(soFar: SO_FAR): MaxMsToWaitBeforePublishingFieldConstructor => ( "maxMsToWaitBeforePublishing" in soFar ? {} : { maxMsToWaitBeforePublishing: (instance: number = 0) => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType, neverDelayPublishing: () => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType, } ) as MaxMsToWaitBeforePublishingFieldConstructor : (soFar: SO_FAR) => MaxMsToWaitBeforePublishingFieldConstructor + const buildMaxMsToWaitBeforePublishingFieldConstructor = (soFar: SO_FAR): MaxMsToWaitBeforePublishingFieldConstructor => ( +>buildMaxMsToWaitBeforePublishingFieldConstructor : (soFar: SO_FAR) => MaxMsToWaitBeforePublishingFieldConstructor +>(soFar: SO_FAR): MaxMsToWaitBeforePublishingFieldConstructor => ( "maxMsToWaitBeforePublishing" in soFar ? {} : { maxMsToWaitBeforePublishing: (instance: number = 0) => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType, neverDelayPublishing: () => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType, } ) as MaxMsToWaitBeforePublishingFieldConstructor : (soFar: SO_FAR) => MaxMsToWaitBeforePublishingFieldConstructor >soFar : SO_FAR >( "maxMsToWaitBeforePublishing" in soFar ? {} : { maxMsToWaitBeforePublishing: (instance: number = 0) => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType, neverDelayPublishing: () => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType, } ) as MaxMsToWaitBeforePublishingFieldConstructor : MaxMsToWaitBeforePublishingFieldConstructor >( "maxMsToWaitBeforePublishing" in soFar ? {} : { maxMsToWaitBeforePublishing: (instance: number = 0) => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType, neverDelayPublishing: () => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType, } ) : {} | { maxMsToWaitBeforePublishing: (instance?: number) => BuildPubSubRecordType; neverDelayPublishing: () => BuildPubSubRecordType; } @@ -319,7 +319,7 @@ export enum PubSubRecordIsStoredInRedisAsA { buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType, >buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType : BuildPubSubRecordType >buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) : BuildPubSubRecordType ->buildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType +>buildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType >Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance}) : SO_FAR & { maxMsToWaitBeforePublishing: number; } >Object.assign : { (target: T, source: U): T & U; (target: T, source1: U, source2: V): T & U & V; (target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; } >Object : ObjectConstructor @@ -338,7 +338,7 @@ export enum PubSubRecordIsStoredInRedisAsA { buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType, >buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType : BuildPubSubRecordType >buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) : BuildPubSubRecordType ->buildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType +>buildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType >Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0}) : SO_FAR & { maxMsToWaitBeforePublishing: number; } >Object.assign : { (target: T, source: U): T & U; (target: T, source1: U, source2: V): T & U & V; (target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; } >Object : ObjectConstructor @@ -352,7 +352,7 @@ export enum PubSubRecordIsStoredInRedisAsA { } ) as MaxMsToWaitBeforePublishingFieldConstructor; - type TypeConstructor = + type TypeConstructor = >TypeConstructor : TypeConstructor SO_FAR extends {identifier: any, record: any, maxMsToWaitBeforePublishing: number, storedAs: PubSubRecordIsStoredInRedisAsA} ? { @@ -373,9 +373,9 @@ export enum PubSubRecordIsStoredInRedisAsA { } : {} - const buildType = (soFar: SO_FAR) => ( ->buildType : (soFar: SO_FAR) => { type?: undefined; fields?: undefined; hasField?: undefined; } | { type: SO_FAR; fields: () => Set; hasField: (fieldName: string | number | symbol) => boolean; } ->(soFar: SO_FAR) => ( "identifier" in soFar && "object" in soFar && "maxMsToWaitBeforePublishing" in soFar && "PubSubRecordIsStoredInRedisAsA" in soFar ? {} : { type: soFar, fields: () => new Set(Object.keys(soFar) as (keyof SO_FAR)[]), hasField: (fieldName: string | number | symbol) => fieldName in soFar } ) : (soFar: SO_FAR) => { type?: undefined; fields?: undefined; hasField?: undefined; } | { type: SO_FAR; fields: () => Set; hasField: (fieldName: string | number | symbol) => boolean; } + const buildType = (soFar: SO_FAR) => ( +>buildType : (soFar: SO_FAR) => { type?: undefined; fields?: undefined; hasField?: undefined; } | { type: SO_FAR; fields: () => Set; hasField: (fieldName: string | number | symbol) => boolean; } +>(soFar: SO_FAR) => ( "identifier" in soFar && "object" in soFar && "maxMsToWaitBeforePublishing" in soFar && "PubSubRecordIsStoredInRedisAsA" in soFar ? {} : { type: soFar, fields: () => new Set(Object.keys(soFar) as (keyof SO_FAR)[]), hasField: (fieldName: string | number | symbol) => fieldName in soFar } ) : (soFar: SO_FAR) => { type?: undefined; fields?: undefined; hasField?: undefined; } | { type: SO_FAR; fields: () => Set; hasField: (fieldName: string | number | symbol) => boolean; } >soFar : SO_FAR >( "identifier" in soFar && "object" in soFar && "maxMsToWaitBeforePublishing" in soFar && "PubSubRecordIsStoredInRedisAsA" in soFar ? {} : { type: soFar, fields: () => new Set(Object.keys(soFar) as (keyof SO_FAR)[]), hasField: (fieldName: string | number | symbol) => fieldName in soFar } ) : {} | { type: SO_FAR; fields: () => Set; hasField: (fieldName: string | number | symbol) => boolean; } @@ -425,7 +425,7 @@ export enum PubSubRecordIsStoredInRedisAsA { } ); - type BuildPubSubRecordType = + type BuildPubSubRecordType = >BuildPubSubRecordType : BuildPubSubRecordType NameFieldConstructor & @@ -435,9 +435,9 @@ export enum PubSubRecordIsStoredInRedisAsA { MaxMsToWaitBeforePublishingFieldConstructor & TypeConstructor - const buildPubSubRecordType = (soFar: SO_FAR) => Object.assign( ->buildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType ->(soFar: SO_FAR) => Object.assign( {}, buildNameFieldConstructor(soFar), buildIdentifierFieldConstructor(soFar), buildRecordFieldConstructor(soFar), buildStoredAsConstructor(soFar), buildMaxMsToWaitBeforePublishingFieldConstructor(soFar), buildType(soFar) ) as BuildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType + const buildPubSubRecordType = (soFar: SO_FAR) => Object.assign( +>buildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType +>(soFar: SO_FAR) => Object.assign( {}, buildNameFieldConstructor(soFar), buildIdentifierFieldConstructor(soFar), buildRecordFieldConstructor(soFar), buildStoredAsConstructor(soFar), buildMaxMsToWaitBeforePublishingFieldConstructor(soFar), buildType(soFar) ) as BuildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType >soFar : SO_FAR >Object.assign( {}, buildNameFieldConstructor(soFar), buildIdentifierFieldConstructor(soFar), buildRecordFieldConstructor(soFar), buildStoredAsConstructor(soFar), buildMaxMsToWaitBeforePublishingFieldConstructor(soFar), buildType(soFar) ) as BuildPubSubRecordType : BuildPubSubRecordType >Object.assign( {}, buildNameFieldConstructor(soFar), buildIdentifierFieldConstructor(soFar), buildRecordFieldConstructor(soFar), buildStoredAsConstructor(soFar), buildMaxMsToWaitBeforePublishingFieldConstructor(soFar), buildType(soFar) ) : any @@ -450,38 +450,38 @@ export enum PubSubRecordIsStoredInRedisAsA { buildNameFieldConstructor(soFar), >buildNameFieldConstructor(soFar) : { name?: undefined; } | { name: (instance?: TYPE) => BuildPubSubRecordType; } ->buildNameFieldConstructor : (soFar: SO_FAR) => { name?: undefined; } | { name: (instance?: TYPE) => BuildPubSubRecordType; } +>buildNameFieldConstructor : (soFar: SO_FAR) => { name?: undefined; } | { name: (instance?: TYPE) => BuildPubSubRecordType; } >soFar : SO_FAR buildIdentifierFieldConstructor(soFar), >buildIdentifierFieldConstructor(soFar) : { identifier?: undefined; } | { identifier: (instance?: TYPE) => BuildPubSubRecordType; } ->buildIdentifierFieldConstructor : (soFar: SO_FAR) => { identifier?: undefined; } | { identifier: (instance?: TYPE) => BuildPubSubRecordType; } +>buildIdentifierFieldConstructor : (soFar: SO_FAR) => { identifier?: undefined; } | { identifier: (instance?: TYPE) => BuildPubSubRecordType; } >soFar : SO_FAR buildRecordFieldConstructor(soFar), >buildRecordFieldConstructor(soFar) : { record?: undefined; } | { record: (instance?: TYPE) => BuildPubSubRecordType; } ->buildRecordFieldConstructor : (soFar: SO_FAR) => { record?: undefined; } | { record: (instance?: TYPE) => BuildPubSubRecordType; } +>buildRecordFieldConstructor : (soFar: SO_FAR) => { record?: undefined; } | { record: (instance?: TYPE) => BuildPubSubRecordType; } >soFar : SO_FAR buildStoredAsConstructor(soFar), >buildStoredAsConstructor(soFar) : { storedAsJsonEncodedRedisString?: undefined; storedAsRedisHash?: undefined; } | { storedAsJsonEncodedRedisString: () => BuildPubSubRecordType; storedAsRedisHash: () => BuildPubSubRecordType; } ->buildStoredAsConstructor : (soFar: SO_FAR) => { storedAsJsonEncodedRedisString?: undefined; storedAsRedisHash?: undefined; } | { storedAsJsonEncodedRedisString: () => BuildPubSubRecordType; storedAsRedisHash: () => BuildPubSubRecordType; } +>buildStoredAsConstructor : (soFar: SO_FAR) => { storedAsJsonEncodedRedisString?: undefined; storedAsRedisHash?: undefined; } | { storedAsJsonEncodedRedisString: () => BuildPubSubRecordType; storedAsRedisHash: () => BuildPubSubRecordType; } >soFar : SO_FAR buildMaxMsToWaitBeforePublishingFieldConstructor(soFar), >buildMaxMsToWaitBeforePublishingFieldConstructor(soFar) : MaxMsToWaitBeforePublishingFieldConstructor ->buildMaxMsToWaitBeforePublishingFieldConstructor : (soFar: SO_FAR) => MaxMsToWaitBeforePublishingFieldConstructor +>buildMaxMsToWaitBeforePublishingFieldConstructor : (soFar: SO_FAR) => MaxMsToWaitBeforePublishingFieldConstructor >soFar : SO_FAR buildType(soFar) >buildType(soFar) : { type?: undefined; fields?: undefined; hasField?: undefined; } | { type: SO_FAR; fields: () => Set; hasField: (fieldName: string | number | symbol) => boolean; } ->buildType : (soFar: SO_FAR) => { type?: undefined; fields?: undefined; hasField?: undefined; } | { type: SO_FAR; fields: () => Set; hasField: (fieldName: string | number | symbol) => boolean; } +>buildType : (soFar: SO_FAR) => { type?: undefined; fields?: undefined; hasField?: undefined; } | { type: SO_FAR; fields: () => Set; hasField: (fieldName: string | number | symbol) => boolean; } >soFar : SO_FAR ) as BuildPubSubRecordType; const PubSubRecordType = buildPubSubRecordType({}); >PubSubRecordType : BuildPubSubRecordType<{}> >buildPubSubRecordType({}) : BuildPubSubRecordType<{}> ->buildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType +>buildPubSubRecordType : (soFar: SO_FAR) => BuildPubSubRecordType >{} : {} diff --git a/tests/baselines/reference/constructorReturningAPrimitive.errors.txt b/tests/baselines/reference/constructorReturningAPrimitive.errors.txt new file mode 100644 index 0000000000000..4fe9563764b77 --- /dev/null +++ b/tests/baselines/reference/constructorReturningAPrimitive.errors.txt @@ -0,0 +1,29 @@ +tests/cases/compiler/constructorReturningAPrimitive.ts(15,9): error TS2322: Type 'T' is not assignable to type 'B'. +tests/cases/compiler/constructorReturningAPrimitive.ts(15,9): error TS2409: Return type of constructor signature must be assignable to the instance type of the class. + + +==== tests/cases/compiler/constructorReturningAPrimitive.ts (2 errors) ==== + // technically not allowed by JavaScript but we don't have a 'not-primitive' constraint + // functionally only possible when your class is otherwise devoid of members so of little consequence in practice + + class A { + constructor() { + return 1; + } + } + + var a = new A(); + + class B { + constructor() { + var x: T; + return x; + ~~~~~~~~~ +!!! error TS2322: Type 'T' is not assignable to type 'B'. +!!! related TS2797 tests/cases/compiler/constructorReturningAPrimitive.ts:12:9: This type parameter likely needs an `extends object` constraint. + ~~~~~~~~~ +!!! error TS2409: Return type of constructor signature must be assignable to the instance type of the class. + } + } + + var b = new B(); \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitExpressionInExtends5.js b/tests/baselines/reference/declarationEmitExpressionInExtends5.js index 41917304e3c8f..79d34834c3fe3 100644 --- a/tests/baselines/reference/declarationEmitExpressionInExtends5.js +++ b/tests/baselines/reference/declarationEmitExpressionInExtends5.js @@ -13,7 +13,7 @@ namespace Test { } - export function getClass() : new() => T + export function getClass() : new() => T { return SomeClass as (new() => T); } @@ -66,6 +66,6 @@ declare namespace Test { const Derived_base: new () => IFace; export class Derived extends Derived_base { } - export function getClass(): new () => T; + export function getClass(): new () => T; export {}; } diff --git a/tests/baselines/reference/declarationEmitExpressionInExtends5.symbols b/tests/baselines/reference/declarationEmitExpressionInExtends5.symbols index 42bf589221147..0c2c52f5298d0 100644 --- a/tests/baselines/reference/declarationEmitExpressionInExtends5.symbols +++ b/tests/baselines/reference/declarationEmitExpressionInExtends5.symbols @@ -20,7 +20,7 @@ namespace Test { } - export function getClass() : new() => T + export function getClass() : new() => T >getClass : Symbol(getClass, Decl(declarationEmitExpressionInExtends5.ts, 12, 2)) >T : Symbol(T, Decl(declarationEmitExpressionInExtends5.ts, 14, 26)) >T : Symbol(T, Decl(declarationEmitExpressionInExtends5.ts, 14, 26)) diff --git a/tests/baselines/reference/declarationEmitExpressionInExtends5.types b/tests/baselines/reference/declarationEmitExpressionInExtends5.types index 4eeae1fdaa00c..9fad0ffc51135 100644 --- a/tests/baselines/reference/declarationEmitExpressionInExtends5.types +++ b/tests/baselines/reference/declarationEmitExpressionInExtends5.types @@ -14,12 +14,12 @@ namespace Test export class Derived extends getClass() >Derived : Derived >getClass() : IFace ->getClass : () => new () => T +>getClass : () => new () => T { } - export function getClass() : new() => T ->getClass : () => new () => T + export function getClass() : new() => T +>getClass : () => new () => T { return SomeClass as (new() => T); >SomeClass as (new() => T) : new () => T diff --git a/tests/baselines/reference/genericCallWithObjectTypeArgsAndIndexersErrors.errors.txt b/tests/baselines/reference/genericCallWithObjectTypeArgsAndIndexersErrors.errors.txt new file mode 100644 index 0000000000000..be740f7a5ca79 --- /dev/null +++ b/tests/baselines/reference/genericCallWithObjectTypeArgsAndIndexersErrors.errors.txt @@ -0,0 +1,30 @@ +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectTypeArgsAndIndexersErrors.ts(10,9): error TS2413: Numeric index type 'T' is not assignable to string index type 'Object'. + + +==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectTypeArgsAndIndexersErrors.ts (1 errors) ==== + // Type inference infers from indexers in target type, error cases + + function foo(x: T) { + return x; + } + + function other(arg: T) { + var b: { + [x: string]: Object; + [x: number]: T; // ok, T is a subtype of Object because its apparent type is {} + ~~~~~~~~~~~~~~~ +!!! error TS2413: Numeric index type 'T' is not assignable to string index type 'Object'. + }; + var r2 = foo(b); // T + } + + function other3(arg: T) { + var b: { + [x: string]: Object; + [x: number]: T; + }; + var r2 = foo(b); + var d = r2[1]; + var e = r2['1']; + var u: U = r2[1]; // ok + } \ No newline at end of file diff --git a/tests/baselines/reference/genericPrototypeProperty3.js b/tests/baselines/reference/genericPrototypeProperty3.js index 9917891837486..5e5492b156bf7 100644 --- a/tests/baselines/reference/genericPrototypeProperty3.js +++ b/tests/baselines/reference/genericPrototypeProperty3.js @@ -1,6 +1,6 @@ //// [genericPrototypeProperty3.ts] class BaseEvent { - target: {}; + target: unknown; } class MyEvent extends BaseEvent { // T is instantiated to any in the prototype, which is assignable to {} diff --git a/tests/baselines/reference/genericPrototypeProperty3.symbols b/tests/baselines/reference/genericPrototypeProperty3.symbols index 7f8c57ff2ea06..678087244bf49 100644 --- a/tests/baselines/reference/genericPrototypeProperty3.symbols +++ b/tests/baselines/reference/genericPrototypeProperty3.symbols @@ -2,7 +2,7 @@ class BaseEvent { >BaseEvent : Symbol(BaseEvent, Decl(genericPrototypeProperty3.ts, 0, 0)) - target: {}; + target: unknown; >target : Symbol(BaseEvent.target, Decl(genericPrototypeProperty3.ts, 0, 17)) } diff --git a/tests/baselines/reference/genericPrototypeProperty3.types b/tests/baselines/reference/genericPrototypeProperty3.types index 4ebc769478842..350100e3644b5 100644 --- a/tests/baselines/reference/genericPrototypeProperty3.types +++ b/tests/baselines/reference/genericPrototypeProperty3.types @@ -2,8 +2,8 @@ class BaseEvent { >BaseEvent : BaseEvent - target: {}; ->target : {} + target: unknown; +>target : unknown } class MyEvent extends BaseEvent { // T is instantiated to any in the prototype, which is assignable to {} diff --git a/tests/baselines/reference/isomorphicMappedTypeInference.js b/tests/baselines/reference/isomorphicMappedTypeInference.js index aa904e9afa173..100e7e56aced8 100644 --- a/tests/baselines/reference/isomorphicMappedTypeInference.js +++ b/tests/baselines/reference/isomorphicMappedTypeInference.js @@ -23,7 +23,7 @@ function boxify(obj: T): Boxified { return result; } -function unboxify(obj: Boxified): T { +function unboxify(obj: Boxified): T { let result = {} as T; for (let k in obj) { result[k] = unbox(obj[k]); @@ -307,7 +307,7 @@ declare type Boxified = { declare function box(x: T): Box; declare function unbox(x: Box): T; declare function boxify(obj: T): Boxified; -declare function unboxify(obj: Boxified): T; +declare function unboxify(obj: Boxified): T; declare function assignBoxified(obj: Boxified, values: T): void; declare function f1(): void; declare function f2(): void; diff --git a/tests/baselines/reference/isomorphicMappedTypeInference.symbols b/tests/baselines/reference/isomorphicMappedTypeInference.symbols index 3192be13ff634..45d97005e3761 100644 --- a/tests/baselines/reference/isomorphicMappedTypeInference.symbols +++ b/tests/baselines/reference/isomorphicMappedTypeInference.symbols @@ -75,10 +75,10 @@ function boxify(obj: T): Boxified { >result : Symbol(result, Decl(isomorphicMappedTypeInference.ts, 17, 7)) } -function unboxify(obj: Boxified): T { +function unboxify(obj: Boxified): T { >unboxify : Symbol(unboxify, Decl(isomorphicMappedTypeInference.ts, 22, 1)) >T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 24, 18)) ->obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 24, 21)) +>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 24, 36)) >Boxified : Symbol(Boxified, Decl(isomorphicMappedTypeInference.ts, 2, 1)) >T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 24, 18)) >T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 24, 18)) @@ -89,13 +89,13 @@ function unboxify(obj: Boxified): T { for (let k in obj) { >k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 26, 12)) ->obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 24, 21)) +>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 24, 36)) result[k] = unbox(obj[k]); >result : Symbol(result, Decl(isomorphicMappedTypeInference.ts, 25, 7)) >k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 26, 12)) >unbox : Symbol(unbox, Decl(isomorphicMappedTypeInference.ts, 10, 1)) ->obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 24, 21)) +>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 24, 36)) >k : Symbol(k, Decl(isomorphicMappedTypeInference.ts, 26, 12)) } return result; diff --git a/tests/baselines/reference/isomorphicMappedTypeInference.types b/tests/baselines/reference/isomorphicMappedTypeInference.types index 1f1fa0d200a0c..2623d0807a692 100644 --- a/tests/baselines/reference/isomorphicMappedTypeInference.types +++ b/tests/baselines/reference/isomorphicMappedTypeInference.types @@ -60,8 +60,8 @@ function boxify(obj: T): Boxified { >result : Boxified } -function unboxify(obj: Boxified): T { ->unboxify : (obj: Boxified) => T +function unboxify(obj: Boxified): T { +>unboxify : (obj: Boxified) => T >obj : Boxified let result = {} as T; @@ -174,7 +174,7 @@ function f2() { let v = unboxify(b); >v : { a: number; b: string; c: boolean; } >unboxify(b) : { a: number; b: string; c: boolean; } ->unboxify : (obj: Boxified) => T +>unboxify : (obj: Boxified) => T >b : { a: Box; b: Box; c: Box; } let x: number = v.a; @@ -251,14 +251,14 @@ function f4() { >boxify(unboxify(b)) : Boxified<{ a: number; b: string; c: boolean; }> >boxify : (obj: T) => Boxified >unboxify(b) : { a: number; b: string; c: boolean; } ->unboxify : (obj: Boxified) => T +>unboxify : (obj: Boxified) => T >b : { a: Box; b: Box; c: Box; } b = unboxify(boxify(b)); >b = unboxify(boxify(b)) : { a: Box; b: Box; c: Box; } >b : { a: Box; b: Box; c: Box; } >unboxify(boxify(b)) : { a: Box; b: Box; c: Box; } ->unboxify : (obj: Boxified) => T +>unboxify : (obj: Boxified) => T >boxify(b) : Boxified<{ a: Box; b: Box; c: Box; }> >boxify : (obj: T) => Boxified >b : { a: Box; b: Box; c: Box; } @@ -304,7 +304,7 @@ function f5(s: string) { let v = unboxify(b); >v : { a: string | number | boolean; b: string | number | boolean; c: string | number | boolean; } >unboxify(b) : { a: string | number | boolean; b: string | number | boolean; c: string | number | boolean; } ->unboxify : (obj: Boxified) => T +>unboxify : (obj: Boxified) => T >b : { a: Box | Box | Box; b: Box | Box | Box; c: Box | Box | Box; } let x: string | number | boolean = v.a; @@ -355,7 +355,7 @@ function f6(s: string) { let v = unboxify(b); >v : { [x: string]: any; } >unboxify(b) : { [x: string]: any; } ->unboxify : (obj: Boxified) => T +>unboxify : (obj: Boxified) => T >b : { [x: string]: Box | Box | Box; } let x: string | number | boolean = v[s]; diff --git a/tests/baselines/reference/keyofAndIndexedAccess.errors.txt b/tests/baselines/reference/keyofAndIndexedAccess.errors.txt new file mode 100644 index 0000000000000..2f5035ea6f565 --- /dev/null +++ b/tests/baselines/reference/keyofAndIndexedAccess.errors.txt @@ -0,0 +1,746 @@ +tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts(316,5): error TS2322: Type 'T' is not assignable to type '{}'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts(317,5): error TS2322: Type 'T[keyof T]' is not assignable to type '{}'. + Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{}'. + Type 'T[string]' is not assignable to type '{}'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts(318,5): error TS2322: Type 'T[K]' is not assignable to type '{}'. + Type 'T[keyof T]' is not assignable to type '{}'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts(323,5): error TS2322: Type 'T' is not assignable to type '{} | null | undefined'. + Type 'T' is not assignable to type '{}'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts(324,5): error TS2322: Type 'T[keyof T]' is not assignable to type '{} | null | undefined'. + Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{} | null | undefined'. + Type 'T[string]' is not assignable to type '{} | null | undefined'. + Type 'T[string]' is not assignable to type '{}'. + Type 'T[keyof T]' is not assignable to type '{}'. + Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{}'. + Type 'T[string]' is not assignable to type '{}'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts(325,5): error TS2322: Type 'T[K]' is not assignable to type '{} | null | undefined'. + Type 'T[keyof T]' is not assignable to type '{} | null | undefined'. + Type 'T[keyof T]' is not assignable to type '{}'. + Type 'T[K]' is not assignable to type '{}'. + Type 'T[keyof T]' is not assignable to type '{}'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts(611,33): error TS2345: Argument of type 'T[K]' is not assignable to parameter of type '{} | null | undefined'. + Type 'T[keyof T]' is not assignable to type '{} | null | undefined'. + Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{} | null | undefined'. + Type 'T[string]' is not assignable to type '{} | null | undefined'. + Type 'T[string]' is not assignable to type '{}'. + Type 'T[keyof T]' is not assignable to type '{}'. + Type 'T[K]' is not assignable to type '{}'. + Type 'T[keyof T]' is not assignable to type '{}'. + Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{}'. + Type 'T[string]' is not assignable to type '{}'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts(619,13): error TS2322: Type 'T[keyof T]' is not assignable to type '{} | null | undefined'. + Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{} | null | undefined'. + Type 'T[string]' is not assignable to type '{} | null | undefined'. + Type 'T[string]' is not assignable to type '{}'. + Type 'T[keyof T]' is not assignable to type '{}'. + Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{}'. + Type 'T[string]' is not assignable to type '{}'. + + +==== tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts (8 errors) ==== + class Shape { + name: string; + width: number; + height: number; + visible: boolean; + } + + class TaggedShape extends Shape { + tag: string; + } + + class Item { + name: string; + price: number; + } + + class Options { + visible: "yes" | "no"; + } + + type Dictionary = { [x: string]: T }; + type NumericallyIndexed = { [x: number]: T }; + + const enum E { A, B, C } + + type K00 = keyof any; // string + type K01 = keyof string; // "toString" | "charAt" | ... + type K02 = keyof number; // "toString" | "toFixed" | "toExponential" | ... + type K03 = keyof boolean; // "valueOf" + type K04 = keyof void; // never + type K05 = keyof undefined; // never + type K06 = keyof null; // never + type K07 = keyof never; // string | number | symbol + type K08 = keyof unknown; // never + + type K10 = keyof Shape; // "name" | "width" | "height" | "visible" + type K11 = keyof Shape[]; // "length" | "toString" | ... + type K12 = keyof Dictionary; // string + type K13 = keyof {}; // never + type K14 = keyof Object; // "constructor" | "toString" | ... + type K15 = keyof E; // "toString" | "toFixed" | "toExponential" | ... + type K16 = keyof [string, number]; // "0" | "1" | "length" | "toString" | ... + type K17 = keyof (Shape | Item); // "name" + type K18 = keyof (Shape & Item); // "name" | "width" | "height" | "visible" | "price" + type K19 = keyof NumericallyIndexed // never + + type KeyOf = keyof T; + + type K20 = KeyOf; // "name" | "width" | "height" | "visible" + type K21 = KeyOf>; // string + + type NAME = "name"; + type WIDTH_OR_HEIGHT = "width" | "height"; + + type Q10 = Shape["name"]; // string + type Q11 = Shape["width" | "height"]; // number + type Q12 = Shape["name" | "visible"]; // string | boolean + + type Q20 = Shape[NAME]; // string + type Q21 = Shape[WIDTH_OR_HEIGHT]; // number + + type Q30 = [string, number][0]; // string + type Q31 = [string, number][1]; // number + type Q32 = [string, number][number]; // string | number + type Q33 = [string, number][E.A]; // string + type Q34 = [string, number][E.B]; // number + type Q35 = [string, number]["0"]; // string + type Q36 = [string, number]["1"]; // string + + type Q40 = (Shape | Options)["visible"]; // boolean | "yes" | "no" + type Q41 = (Shape & Options)["visible"]; // true & "yes" | true & "no" | false & "yes" | false & "no" + + type Q50 = Dictionary["howdy"]; // Shape + type Q51 = Dictionary[123]; // Shape + type Q52 = Dictionary[E.B]; // Shape + + declare let cond: boolean; + + function getProperty(obj: T, key: K) { + return obj[key]; + } + + function setProperty(obj: T, key: K, value: T[K]) { + obj[key] = value; + } + + function f10(shape: Shape) { + let name = getProperty(shape, "name"); // string + let widthOrHeight = getProperty(shape, cond ? "width" : "height"); // number + let nameOrVisible = getProperty(shape, cond ? "name" : "visible"); // string | boolean + setProperty(shape, "name", "rectangle"); + setProperty(shape, cond ? "width" : "height", 10); + setProperty(shape, cond ? "name" : "visible", true); // Technically not safe + } + + function f11(a: Shape[]) { + let len = getProperty(a, "length"); // number + setProperty(a, "length", len); + } + + function f12(t: [Shape, boolean]) { + let len = getProperty(t, "length"); + let s2 = getProperty(t, "0"); // Shape + let b2 = getProperty(t, "1"); // boolean + } + + function f13(foo: any, bar: any) { + let x = getProperty(foo, "x"); // any + let y = getProperty(foo, "100"); // any + let z = getProperty(foo, bar); // any + } + + class Component { + props: PropType; + getProperty(key: K) { + return this.props[key]; + } + setProperty(key: K, value: PropType[K]) { + this.props[key] = value; + } + } + + function f20(component: Component) { + let name = component.getProperty("name"); // string + let widthOrHeight = component.getProperty(cond ? "width" : "height"); // number + let nameOrVisible = component.getProperty(cond ? "name" : "visible"); // string | boolean + component.setProperty("name", "rectangle"); + component.setProperty(cond ? "width" : "height", 10) + component.setProperty(cond ? "name" : "visible", true); // Technically not safe + } + + function pluck(array: T[], key: K) { + return array.map(x => x[key]); + } + + function f30(shapes: Shape[]) { + let names = pluck(shapes, "name"); // string[] + let widths = pluck(shapes, "width"); // number[] + let nameOrVisibles = pluck(shapes, cond ? "name" : "visible"); // (string | boolean)[] + } + + function f31(key: K) { + const shape: Shape = { name: "foo", width: 5, height: 10, visible: true }; + return shape[key]; // Shape[K] + } + + function f32(key: K) { + const shape: Shape = { name: "foo", width: 5, height: 10, visible: true }; + return shape[key]; // Shape[K] + } + + function f33(shape: S, key: K) { + let name = getProperty(shape, "name"); + let prop = getProperty(shape, key); + return prop; + } + + function f34(ts: TaggedShape) { + let tag1 = f33(ts, "tag"); + let tag2 = getProperty(ts, "tag"); + } + + class C { + public x: string; + protected y: string; + private z: string; + } + + // Indexed access expressions have always permitted access to private and protected members. + // For consistency we also permit such access in indexed access types. + function f40(c: C) { + type X = C["x"]; + type Y = C["y"]; + type Z = C["z"]; + let x: X = c["x"]; + let y: Y = c["y"]; + let z: Z = c["z"]; + } + + function f50(k: keyof T, s: string) { + const x1 = s as keyof T; + const x2 = k as string; + } + + function f51(k: K, s: string) { + const x1 = s as keyof T; + const x2 = k as string; + } + + function f52(obj: { [x: string]: boolean }, k: Exclude, s: string, n: number) { + const x1 = obj[s]; + const x2 = obj[n]; + const x3 = obj[k]; + } + + function f53>(obj: { [x: string]: boolean }, k: K, s: string, n: number) { + const x1 = obj[s]; + const x2 = obj[n]; + const x3 = obj[k]; + } + + function f54(obj: T, key: keyof T) { + for (let s in obj[key]) { + } + const b = "foo" in obj[key]; + } + + function f55(obj: T, key: K) { + for (let s in obj[key]) { + } + const b = "foo" in obj[key]; + } + + function f60(source: T, target: T) { + for (let k in source) { + target[k] = source[k]; + } + } + + function f70(func: (k1: keyof (T | U), k2: keyof (T & U)) => void) { + func<{ a: any, b: any }, { a: any, c: any }>('a', 'a'); + func<{ a: any, b: any }, { a: any, c: any }>('a', 'b'); + func<{ a: any, b: any }, { a: any, c: any }>('a', 'c'); + } + + function f71(func: (x: T, y: U) => Partial) { + let x = func({ a: 1, b: "hello" }, { c: true }); + x.a; // number | undefined + x.b; // string | undefined + x.c; // boolean | undefined + } + + function f72(func: (x: T, y: U, k: K) => (T & U)[K]) { + let a = func({ a: 1, b: "hello" }, { c: true }, 'a'); // number + let b = func({ a: 1, b: "hello" }, { c: true }, 'b'); // string + let c = func({ a: 1, b: "hello" }, { c: true }, 'c'); // boolean + } + + function f73(func: (x: T, y: U, k: K) => (T & U)[K]) { + let a = func({ a: 1, b: "hello" }, { c: true }, 'a'); // number + let b = func({ a: 1, b: "hello" }, { c: true }, 'b'); // string + let c = func({ a: 1, b: "hello" }, { c: true }, 'c'); // boolean + } + + function f74(func: (x: T, y: U, k: K) => (T | U)[K]) { + let a = func({ a: 1, b: "hello" }, { a: 2, b: true }, 'a'); // number + let b = func({ a: 1, b: "hello" }, { a: 2, b: true }, 'b'); // string | boolean + } + + function f80(obj: T) { + let a1 = obj.a; // { x: any } + let a2 = obj['a']; // { x: any } + let a3 = obj['a'] as T['a']; // T["a"] + let x1 = obj.a.x; // any + let x2 = obj['a']['x']; // any + let x3 = obj['a']['x'] as T['a']['x']; // T["a"]["x"] + } + + function f81(obj: T) { + return obj['a']['x'] as T['a']['x']; + } + + function f82() { + let x1 = f81({ a: { x: "hello" } }); // string + let x2 = f81({ a: { x: 42 } }); // number + } + + function f83(obj: T, key: K) { + return obj[key]['x'] as T[K]['x']; + } + + function f84() { + let x1 = f83({ foo: { x: "hello" } }, "foo"); // string + let x2 = f83({ bar: { x: 42 } }, "bar"); // number + } + + class C1 { + x: number; + get(key: K) { + return this[key]; + } + set(key: K, value: this[K]) { + this[key] = value; + } + foo() { + let x1 = this.x; // number + let x2 = this["x"]; // number + let x3 = this.get("x"); // this["x"] + let x4 = getProperty(this, "x"); // this["x"] + this.x = 42; + this["x"] = 42; + this.set("x", 42); + setProperty(this, "x", 42); + } + } + + type S2 = { + a: string; + b: string; + }; + + function f90(x1: S2[keyof S2], x2: T[keyof S2], x3: S2[K]) { + x1 = x2; + x1 = x3; + x2 = x1; + x2 = x3; + x3 = x1; + x3 = x2; + x1.length; + x2.length; + x3.length; + } + + function f91(x: T, y: T[keyof T], z: T[K]) { + let a: {}; + a = x; + ~ +!!! error TS2322: Type 'T' is not assignable to type '{}'. +!!! related TS2797 tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts:314:14: This type parameter likely needs an `extends object` constraint. + a = y; + ~ +!!! error TS2322: Type 'T[keyof T]' is not assignable to type '{}'. +!!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{}'. +!!! error TS2322: Type 'T[string]' is not assignable to type '{}'. + a = z; + ~ +!!! error TS2322: Type 'T[K]' is not assignable to type '{}'. +!!! error TS2322: Type 'T[keyof T]' is not assignable to type '{}'. + } + + function f92(x: T, y: T[keyof T], z: T[K]) { + let a: {} | null | undefined; + a = x; + ~ +!!! error TS2322: Type 'T' is not assignable to type '{} | null | undefined'. +!!! error TS2322: Type 'T' is not assignable to type '{}'. +!!! related TS2797 tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts:321:14: This type parameter likely needs an `extends object` constraint. +!!! related TS2797 tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts:321:14: This type parameter likely needs an `extends object` constraint. + a = y; + ~ +!!! error TS2322: Type 'T[keyof T]' is not assignable to type '{} | null | undefined'. +!!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{} | null | undefined'. +!!! error TS2322: Type 'T[string]' is not assignable to type '{} | null | undefined'. +!!! error TS2322: Type 'T[string]' is not assignable to type '{}'. +!!! error TS2322: Type 'T[keyof T]' is not assignable to type '{}'. +!!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{}'. +!!! error TS2322: Type 'T[string]' is not assignable to type '{}'. + a = z; + ~ +!!! error TS2322: Type 'T[K]' is not assignable to type '{} | null | undefined'. +!!! error TS2322: Type 'T[keyof T]' is not assignable to type '{} | null | undefined'. +!!! error TS2322: Type 'T[keyof T]' is not assignable to type '{}'. +!!! error TS2322: Type 'T[K]' is not assignable to type '{}'. +!!! error TS2322: Type 'T[keyof T]' is not assignable to type '{}'. + } + + // Repros from #12011 + + class Base { + get(prop: K) { + return this[prop]; + } + set(prop: K, value: this[K]) { + this[prop] = value; + } + } + + class Person extends Base { + parts: number; + constructor(parts: number) { + super(); + this.set("parts", parts); + } + getParts() { + return this.get("parts") + } + } + + class OtherPerson { + parts: number; + constructor(parts: number) { + setProperty(this, "parts", parts); + } + getParts() { + return getProperty(this, "parts") + } + } + + // Modified repro from #12544 + + function path(obj: T, key1: K1): T[K1]; + function path(obj: T, key1: K1, key2: K2): T[K1][K2]; + function path(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; + function path(obj: any, ...keys: (string | number)[]): any; + function path(obj: any, ...keys: (string | number)[]): any { + let result = obj; + for (let k of keys) { + result = result[k]; + } + return result; + } + + type Thing = { + a: { x: number, y: string }, + b: boolean + }; + + + function f1(thing: Thing) { + let x1 = path(thing, 'a'); // { x: number, y: string } + let x2 = path(thing, 'a', 'y'); // string + let x3 = path(thing, 'b'); // boolean + let x4 = path(thing, ...['a', 'x']); // any + } + + // Repro from comment in #12114 + + const assignTo2 = (object: T, key1: K1, key2: K2) => + (value: T[K1][K2]) => object[key1][key2] = value; + + // Modified repro from #12573 + + declare function one(handler: (t: T) => void): T + var empty = one(() => {}) // inferred as {}, expected + + type Handlers = { [K in keyof T]: (t: T[K]) => void } + declare function on(handlerHash: Handlers): T + var hashOfEmpty1 = on({ test: () => {} }); // {} + var hashOfEmpty2 = on({ test: (x: boolean) => {} }); // { test: boolean } + + // Repro from #12624 + + interface Options1 { + data?: Data + computed?: Computed; + } + + declare class Component1 { + constructor(options: Options1); + get(key: K): (Data & Computed)[K]; + } + + let c1 = new Component1({ + data: { + hello: "" + } + }); + + c1.get("hello"); + + // Repro from #12625 + + interface Options2 { + data?: Data + computed?: Computed; + } + + declare class Component2 { + constructor(options: Options2); + get(key: K): (Data & Computed)[K]; + } + + // Repro from #12641 + + interface R { + p: number; + } + + function f(p: K) { + let a: any; + a[p].add; // any + } + + // Repro from #12651 + + type MethodDescriptor = { + name: string; + args: any[]; + returnValue: any; + } + + declare function dispatchMethod(name: M['name'], args: M['args']): M['returnValue']; + + type SomeMethodDescriptor = { + name: "someMethod"; + args: [string, number]; + returnValue: string[]; + } + + let result = dispatchMethod("someMethod", ["hello", 35]); + + // Repro from #13073 + + type KeyTypes = "a" | "b" + let MyThingy: { [key in KeyTypes]: string[] }; + + function addToMyThingy(key: S) { + MyThingy[key].push("a"); + } + + // Repro from #13102 + + type Handler = { + onChange: (name: keyof T) => void; + }; + + function onChangeGenericFunction(handler: Handler) { + handler.onChange('preset') + } + + // Repro from #13285 + + function updateIds, K extends string>( + obj: T, + idFields: K[], + idMapping: Partial> + ): Record { + for (const idField of idFields) { + const newId: T[K] | undefined = idMapping[obj[idField]]; + if (newId) { + obj[idField] = newId; + } + } + return obj; + } + + // Repro from #13285 + + function updateIds2( + obj: T, + key: K, + stringMap: { [oldId: string]: string } + ) { + var x = obj[key]; + stringMap[x]; // Should be OK. + } + + // Repro from #13514 + + declare function head>(list: T): T[0]; + + // Repro from #13604 + + class A { + props: T & { foo: string }; + } + + class B extends A<{ x: number}> { + f(p: this["props"]) { + p.x; + } + } + + // Repro from #13749 + + class Form { + private childFormFactories: {[K in keyof T]: (v: T[K]) => Form} + + public set(prop: K, value: T[K]) { + this.childFormFactories[prop](value) + } + } + + // Repro from #13787 + + class SampleClass

{ + public props: Readonly

; + constructor(props: P) { + this.props = Object.freeze(props); + } + } + + interface Foo { + foo: string; + } + + declare function merge(obj1: T, obj2: U): T & U; + + class AnotherSampleClass extends SampleClass { + constructor(props: T) { + const foo: Foo = { foo: "bar" }; + super(merge(props, foo)); + } + + public brokenMethod() { + this.props.foo.concat; + } + } + new AnotherSampleClass({}); + + // Positive repro from #17166 + function f3>(t: T, k: K, tk: T[K]): void { + for (let key in t) { + key = k // ok, K ==> keyof T + t[key] = tk; // ok, T[K] ==> T[keyof T] + } + } + + // # 21185 + type Predicates = { + [T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T] + } + + // Repros from #23592 + + type Example = { [K in keyof T]: T[K]["prop"] }; + type Result = Example<{ a: { prop: string }; b: { prop: number } }>; + + type Helper2 = { [K in keyof T]: Extract }; + type Example2 = { [K in keyof Helper2]: Helper2[K]["prop"] }; + type Result2 = Example2<{ 1: { prop: string }; 2: { prop: number } }>; + + // Repro from #23618 + + type DBBoolTable = { [k in K]: 0 | 1 } + enum Flag { + FLAG_1 = "flag_1", + FLAG_2 = "flag_2" + } + + type SimpleDBRecord = { staticField: number } & DBBoolTable + function getFlagsFromSimpleRecord(record: SimpleDBRecord, flags: Flag[]) { + return record[flags[0]]; + } + + type DynamicDBRecord = ({ dynamicField: number } | { dynamicField: string }) & DBBoolTable + function getFlagsFromDynamicRecord(record: DynamicDBRecord, flags: Flag[]) { + return record[flags[0]]; + } + + // Repro from #21368 + + interface I { + foo: string; + } + + declare function take(p: T): void; + + function fn(o: T, k: K) { + take<{} | null | undefined>(o[k]); + ~~~~ +!!! error TS2345: Argument of type 'T[K]' is not assignable to parameter of type '{} | null | undefined'. +!!! error TS2345: Type 'T[keyof T]' is not assignable to type '{} | null | undefined'. +!!! error TS2345: Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{} | null | undefined'. +!!! error TS2345: Type 'T[string]' is not assignable to type '{} | null | undefined'. +!!! error TS2345: Type 'T[string]' is not assignable to type '{}'. +!!! error TS2345: Type 'T[keyof T]' is not assignable to type '{}'. +!!! error TS2345: Type 'T[K]' is not assignable to type '{}'. +!!! error TS2345: Type 'T[keyof T]' is not assignable to type '{}'. +!!! error TS2345: Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{}'. +!!! error TS2345: Type 'T[string]' is not assignable to type '{}'. + take(o[k]); + } + + // Repro from #23133 + + class Unbounded { + foo(x: T[keyof T]) { + let y: {} | undefined | null = x; + ~ +!!! error TS2322: Type 'T[keyof T]' is not assignable to type '{} | null | undefined'. +!!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{} | null | undefined'. +!!! error TS2322: Type 'T[string]' is not assignable to type '{} | null | undefined'. +!!! error TS2322: Type 'T[string]' is not assignable to type '{}'. +!!! error TS2322: Type 'T[keyof T]' is not assignable to type '{}'. +!!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{}'. +!!! error TS2322: Type 'T[string]' is not assignable to type '{}'. + } + } + + // Repro from #23940 + + interface I7 { + x: any; + } + type Foo7 = T; + declare function f7(type: K): Foo7; + + // Repro from #21770 + + type Dict = { [key in T]: number }; + type DictDict = { [key in V]: Dict }; + + function ff1(dd: DictDict, k1: V, k2: T): number { + return dd[k1][k2]; + } + + function ff2(dd: DictDict, k1: V, k2: T): number { + const d: Dict = dd[k1]; + return d[k2]; + } + + // Repro from #26409 + + const cf1 = (t: T, k: K) => + { + const s: string = t[k]; + t.cool; + }; + + const cf2 = (t: T, k: K) => + { + const s: string = t[k]; + t.cool; + }; + \ No newline at end of file diff --git a/tests/baselines/reference/logicalOrOperatorWithTypeParameters.errors.txt b/tests/baselines/reference/logicalOrOperatorWithTypeParameters.errors.txt new file mode 100644 index 0000000000000..062ec8b5df6f1 --- /dev/null +++ b/tests/baselines/reference/logicalOrOperatorWithTypeParameters.errors.txt @@ -0,0 +1,38 @@ +tests/cases/conformance/expressions/binaryOperators/logicalOrOperator/logicalOrOperatorWithTypeParameters.ts(5,9): error TS2322: Type 'T | U' is not assignable to type '{}'. + Type 'T' is not assignable to type '{}'. +tests/cases/conformance/expressions/binaryOperators/logicalOrOperator/logicalOrOperatorWithTypeParameters.ts(14,9): error TS2322: Type 'U | V' is not assignable to type '{}'. + Type 'U' is not assignable to type '{}'. + + +==== tests/cases/conformance/expressions/binaryOperators/logicalOrOperator/logicalOrOperatorWithTypeParameters.ts (2 errors) ==== + function fn1(t: T, u: U) { + var r1 = t || t; + var r2: T = t || t; + var r3 = t || u; + var r4: {} = t || u; + ~~ +!!! error TS2322: Type 'T | U' is not assignable to type '{}'. +!!! error TS2322: Type 'T' is not assignable to type '{}'. +!!! related TS2797 tests/cases/conformance/expressions/binaryOperators/logicalOrOperator/logicalOrOperatorWithTypeParameters.ts:1:14: This type parameter likely needs an `extends object` constraint. + } + + function fn2(t: T, u: U, v: V) { + var r1 = t || u; + //var r2: T = t || u; + var r3 = u || u; + var r4: U = u || u; + var r5 = u || v; + var r6: {} = u || v; + ~~ +!!! error TS2322: Type 'U | V' is not assignable to type '{}'. +!!! error TS2322: Type 'U' is not assignable to type '{}'. +!!! related TS2797 tests/cases/conformance/expressions/binaryOperators/logicalOrOperator/logicalOrOperatorWithTypeParameters.ts:8:17: This type parameter likely needs an `extends object` constraint. + //var r7: T = u || v; + } + + function fn3(t: T, u: U) { + var r1 = t || u; + var r2: {} = t || u; + var r3 = t || { a: '' }; + var r4: { a: string } = t || u; + } \ No newline at end of file diff --git a/tests/baselines/reference/mappedTypesAndObjects.errors.txt b/tests/baselines/reference/mappedTypesAndObjects.errors.txt new file mode 100644 index 0000000000000..b8d38c4b8e8fe --- /dev/null +++ b/tests/baselines/reference/mappedTypesAndObjects.errors.txt @@ -0,0 +1,54 @@ +tests/cases/conformance/types/mapped/mappedTypesAndObjects.ts(25,11): error TS2430: Interface 'E1' incorrectly extends interface 'Base'. + Types of property 'foo' are incompatible. + Type 'T' is not assignable to type '{ [key: string]: any; }'. + + +==== tests/cases/conformance/types/mapped/mappedTypesAndObjects.ts (1 errors) ==== + function f1(x: Partial, y: Readonly) { + let obj: {}; + obj = x; + obj = y; + } + + function f2(x: Partial, y: Readonly) { + let obj: { [x: string]: any }; + obj = x; + obj = y; + } + + function f3(x: Partial) { + x = {}; + } + + // Repro from #12900 + + interface Base { + foo: { [key: string]: any }; + bar: any; + baz: any; + } + + interface E1 extends Base { + ~~ +!!! error TS2430: Interface 'E1' incorrectly extends interface 'Base'. +!!! error TS2430: Types of property 'foo' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type '{ [key: string]: any; }'. +!!! related TS2797 tests/cases/conformance/types/mapped/mappedTypesAndObjects.ts:25:14: This type parameter likely needs an `extends object` constraint. + foo: T; + } + + interface Something { name: string, value: string }; + interface E2 extends Base { + foo: Partial; // or other mapped type + } + + interface E3 extends Base { + foo: Partial; // or other mapped type + } + + // Repro from #13747 + + class Form { + private values: {[P in keyof T]?: T[P]} = {} + } + \ No newline at end of file diff --git a/tests/baselines/reference/subclassThisTypeAssignable.errors.txt b/tests/baselines/reference/subclassThisTypeAssignable.errors.txt index f1d661695d1e3..d20443b5ad6e3 100644 --- a/tests/baselines/reference/subclassThisTypeAssignable.errors.txt +++ b/tests/baselines/reference/subclassThisTypeAssignable.errors.txt @@ -1,9 +1,14 @@ +tests/cases/compiler/tile1.ts(2,30): error TS2344: Type 'State' does not satisfy the constraint 'Lifecycle'. tests/cases/compiler/tile1.ts(6,81): error TS2744: Type parameter defaults can only reference previously declared type parameters. +tests/cases/compiler/tile1.ts(11,40): error TS2344: Type 'State' does not satisfy the constraint 'Lifecycle'. -==== tests/cases/compiler/tile1.ts (1 errors) ==== +==== tests/cases/compiler/tile1.ts (3 errors) ==== interface Lifecycle { oninit?(vnode: Vnode): number; + ~~~~~ +!!! error TS2344: Type 'State' does not satisfy the constraint 'Lifecycle'. +!!! related TS2797 tests/cases/compiler/tile1.ts:1:28: This type parameter likely needs an `extends object` constraint. [_: number]: any; } @@ -15,6 +20,9 @@ tests/cases/compiler/tile1.ts(6,81): error TS2744: Type parameter defaults can o interface Component { view(this: State, vnode: Vnode): number; + ~~~~~ +!!! error TS2344: Type 'State' does not satisfy the constraint 'Lifecycle'. +!!! related TS2797 tests/cases/compiler/tile1.ts:10:28: This type parameter likely needs an `extends object` constraint. } interface ClassComponent extends Lifecycle> { diff --git a/tests/baselines/reference/subtypesOfTypeParameter.types b/tests/baselines/reference/subtypesOfTypeParameter.types index 02d4d527786b0..9c5e496a924e6 100644 --- a/tests/baselines/reference/subtypesOfTypeParameter.types +++ b/tests/baselines/reference/subtypesOfTypeParameter.types @@ -393,31 +393,31 @@ function f2(x: T, y: U) { } var r19 = true ? new Object() : x; // BCT is Object ->r19 : Object ->true ? new Object() : x : Object +>r19 : Object | T +>true ? new Object() : x : Object | T >true : true >new Object() : Object >Object : ObjectConstructor >x : T var r19 = true ? x : new Object(); // BCT is Object ->r19 : Object ->true ? x : new Object() : Object +>r19 : Object | T +>true ? x : new Object() : Object | T >true : true >x : T >new Object() : Object >Object : ObjectConstructor var r20 = true ? {} : x; // ok ->r20 : {} ->true ? {} : x : {} +>r20 : T | {} +>true ? {} : x : T | {} >true : true >{} : {} >x : T var r20 = true ? x : {}; // ok ->r20 : {} ->true ? x : {} : {} +>r20 : T | {} +>true ? x : {} : T | {} >true : true >x : T >{} : {} diff --git a/tests/baselines/reference/subtypingWithOptionalProperties.errors.txt b/tests/baselines/reference/subtypingWithOptionalProperties.errors.txt new file mode 100644 index 0000000000000..dd935c01ac45a --- /dev/null +++ b/tests/baselines/reference/subtypingWithOptionalProperties.errors.txt @@ -0,0 +1,17 @@ +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithOptionalProperties.ts(5,9): error TS2322: Type 'T' is not assignable to type '{ s?: number; }'. + + +==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithOptionalProperties.ts (1 errors) ==== + // subtyping is not transitive due to optional properties but the subtyping algorithm assumes it is for the 99% case + + // returns { s?: number; } + function f(a: T) { + var b: { s?: number } = a; + ~ +!!! error TS2322: Type 'T' is not assignable to type '{ s?: number; }'. +!!! related TS2797 tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithOptionalProperties.ts:4:12: This type parameter likely needs an `extends object` constraint. + return b; + } + + var r = f({ s: new Object() }); // ok + r.s && r.s.toFixed(); // would blow up at runtime \ No newline at end of file diff --git a/tests/baselines/reference/tsxGenericAttributesType5.errors.txt b/tests/baselines/reference/tsxGenericAttributesType5.errors.txt new file mode 100644 index 0000000000000..9dbbccf62580f --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType5.errors.txt @@ -0,0 +1,24 @@ +tests/cases/conformance/jsx/file.tsx(9,5): error TS2416: Property 'props' in type 'B' is not assignable to the same property in base type 'Component'. + Type 'U' is not assignable to type 'U & { children?: ReactNode; }'. + Type 'U' is not assignable to type '{ children?: ReactNode; }'. + + +==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== + import React = require('react'); + + class B1 extends React.Component { + render() { + return

; + } + } + class B extends React.Component { + props: U; + ~~~~~ +!!! error TS2416: Property 'props' in type 'B' is not assignable to the same property in base type 'Component'. +!!! error TS2416: Type 'U' is not assignable to type 'U & { children?: ReactNode; }'. +!!! error TS2416: Type 'U' is not assignable to type '{ children?: ReactNode; }'. +!!! related TS2797 tests/cases/conformance/jsx/file.tsx:8:9: This type parameter likely needs an `extends object` constraint. + render() { + return ; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/tsxGenericAttributesType6.errors.txt b/tests/baselines/reference/tsxGenericAttributesType6.errors.txt new file mode 100644 index 0000000000000..efce3382cc091 --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType6.errors.txt @@ -0,0 +1,24 @@ +tests/cases/conformance/jsx/file.tsx(9,5): error TS2416: Property 'props' in type 'B' is not assignable to the same property in base type 'Component'. + Type 'U' is not assignable to type 'U & { children?: ReactNode; }'. + Type 'U' is not assignable to type '{ children?: ReactNode; }'. + + +==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== + import React = require('react'); + + class B1 extends React.Component { + render() { + return
hi
; + } + } + class B extends React.Component { + props: U; + ~~~~~ +!!! error TS2416: Property 'props' in type 'B' is not assignable to the same property in base type 'Component'. +!!! error TS2416: Type 'U' is not assignable to type 'U & { children?: ReactNode; }'. +!!! error TS2416: Type 'U' is not assignable to type '{ children?: ReactNode; }'. +!!! related TS2797 tests/cases/conformance/jsx/file.tsx:8:9: This type parameter likely needs an `extends object` constraint. + render() { + return ; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/tsxGenericAttributesType7.errors.txt b/tests/baselines/reference/tsxGenericAttributesType7.errors.txt new file mode 100644 index 0000000000000..7a6bd1103b6ac --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType7.errors.txt @@ -0,0 +1,19 @@ +tests/cases/conformance/jsx/file.tsx(5,13): error TS2322: Type 'U' is not assignable to type 'IntrinsicAttributes & U'. + Type 'U' is not assignable to type 'IntrinsicAttributes'. + + +==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== + import React = require('react'); + + declare function Component(props: T) : JSX.Element; + const decorator = function (props: U) { + return ; + ~~~~~~~~~ +!!! error TS2322: Type 'U' is not assignable to type 'IntrinsicAttributes & U'. +!!! error TS2322: Type 'U' is not assignable to type 'IntrinsicAttributes'. +!!! related TS2797 tests/cases/conformance/jsx/file.tsx:4:29: This type parameter likely needs an `extends object` constraint. + } + + const decorator1 = function (props: U) { + return ; + } \ No newline at end of file diff --git a/tests/baselines/reference/tsxGenericAttributesType8.errors.txt b/tests/baselines/reference/tsxGenericAttributesType8.errors.txt new file mode 100644 index 0000000000000..4e97859afa284 --- /dev/null +++ b/tests/baselines/reference/tsxGenericAttributesType8.errors.txt @@ -0,0 +1,19 @@ +tests/cases/conformance/jsx/file.tsx(5,13): error TS2322: Type 'U' is not assignable to type 'IntrinsicAttributes & U'. + Type 'U' is not assignable to type 'IntrinsicAttributes'. + + +==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== + import React = require('react'); + + declare function Component(props: T) : JSX.Element; + const decorator = function (props: U) { + return ; + ~~~~~~~~~ +!!! error TS2322: Type 'U' is not assignable to type 'IntrinsicAttributes & U'. +!!! error TS2322: Type 'U' is not assignable to type 'IntrinsicAttributes'. +!!! related TS2797 tests/cases/conformance/jsx/file.tsx:4:29: This type parameter likely needs an `extends object` constraint. + } + + const decorator1 = function (props: U) { + return ; + } \ No newline at end of file diff --git a/tests/baselines/reference/tsxNotUsingApparentTypeOfSFC.errors.txt b/tests/baselines/reference/tsxNotUsingApparentTypeOfSFC.errors.txt index 81231a345627b..d40f7d14e38d4 100644 --- a/tests/baselines/reference/tsxNotUsingApparentTypeOfSFC.errors.txt +++ b/tests/baselines/reference/tsxNotUsingApparentTypeOfSFC.errors.txt @@ -5,9 +5,18 @@ tests/cases/compiler/tsxNotUsingApparentTypeOfSFC.tsx(15,14): error TS2769: No o Type '{}' is not assignable to type 'Readonly

'. Overload 2 of 2, '(props: P, context?: any): MyComponent', gave the following error. Type '{}' is not assignable to type 'Readonly

'. +tests/cases/compiler/tsxNotUsingApparentTypeOfSFC.tsx(17,14): error TS2322: Type 'P' is not assignable to type 'IntrinsicAttributes & P'. + Type 'P' is not assignable to type 'IntrinsicAttributes'. +tests/cases/compiler/tsxNotUsingApparentTypeOfSFC.tsx(18,14): error TS2769: No overload matches this call. + Overload 1 of 2, '(props: Readonly

): MyComponent', gave the following error. + Type 'P' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Readonly<{ children?: ReactNode; }> & Readonly

'. + Type 'P' is not assignable to type 'IntrinsicAttributes'. + Overload 2 of 2, '(props: P, context?: any): MyComponent', gave the following error. + Type 'P' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Readonly<{ children?: ReactNode; }> & Readonly

'. + Type 'P' is not assignable to type 'IntrinsicAttributes'. -==== tests/cases/compiler/tsxNotUsingApparentTypeOfSFC.tsx (2 errors) ==== +==== tests/cases/compiler/tsxNotUsingApparentTypeOfSFC.tsx (4 errors) ==== /// import React from 'react'; @@ -34,5 +43,19 @@ tests/cases/compiler/tsxNotUsingApparentTypeOfSFC.tsx(15,14): error TS2769: No o !!! error TS2769: Type '{}' is not assignable to type 'Readonly

'. let z = // should work + ~~~~~ +!!! error TS2322: Type 'P' is not assignable to type 'IntrinsicAttributes & P'. +!!! error TS2322: Type 'P' is not assignable to type 'IntrinsicAttributes'. +!!! related TS2797 tests/cases/compiler/tsxNotUsingApparentTypeOfSFC.tsx:5:15: This type parameter likely needs an `extends object` constraint. let q = // should work + ~~~~~~~~~~~ +!!! error TS2769: No overload matches this call. +!!! error TS2769: Overload 1 of 2, '(props: Readonly

): MyComponent', gave the following error. +!!! error TS2769: Type 'P' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Readonly<{ children?: ReactNode; }> & Readonly

'. +!!! error TS2769: Type 'P' is not assignable to type 'IntrinsicAttributes'. +!!! error TS2769: Overload 2 of 2, '(props: P, context?: any): MyComponent', gave the following error. +!!! error TS2769: Type 'P' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Readonly<{ children?: ReactNode; }> & Readonly

'. +!!! error TS2769: Type 'P' is not assignable to type 'IntrinsicAttributes'. +!!! related TS2797 tests/cases/compiler/tsxNotUsingApparentTypeOfSFC.tsx:5:15: This type parameter likely needs an `extends object` constraint. +!!! related TS2797 tests/cases/compiler/tsxNotUsingApparentTypeOfSFC.tsx:5:15: This type parameter likely needs an `extends object` constraint. } \ No newline at end of file diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments2.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments2.errors.txt index d31c2afc5607a..2374a12eb1237 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments2.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments2.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/jsx/file.tsx(8,43): error TS2322: Type 'number' is not assignable to type 'string'. tests/cases/conformance/jsx/file.tsx(13,15): error TS2322: Type 'T' is not assignable to type 'IntrinsicAttributes & { prop: unknown; "ignore-prop": string; }'. - Type 'T' is not assignable to type '{ prop: unknown; "ignore-prop": string; }'. + Type 'T' is not assignable to type 'IntrinsicAttributes'. tests/cases/conformance/jsx/file.tsx(20,19): error TS2322: Type '(a: number, b: string) => void' is not assignable to type '(arg: number) => void'. tests/cases/conformance/jsx/file.tsx(31,52): error TS2322: Type '(val: string) => void' is not assignable to type '(selectedVal: number) => void'. Types of parameters 'val' and 'selectedVal' are incompatible. @@ -26,7 +26,8 @@ tests/cases/conformance/jsx/file.tsx(31,52): error TS2322: Type '(val: string) = let a0 = ~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type 'T' is not assignable to type 'IntrinsicAttributes & { prop: unknown; "ignore-prop": string; }'. -!!! error TS2322: Type 'T' is not assignable to type '{ prop: unknown; "ignore-prop": string; }'. +!!! error TS2322: Type 'T' is not assignable to type 'IntrinsicAttributes'. +!!! related TS2797 tests/cases/conformance/jsx/file.tsx:12:14: This type parameter likely needs an `extends object` constraint. } declare function Link(l: {func: (arg: U)=>void}): JSX.Element; diff --git a/tests/baselines/reference/typeInferenceTypePredicate.js b/tests/baselines/reference/typeInferenceTypePredicate.js index bcac004a20383..39e50c8a2d988 100644 --- a/tests/baselines/reference/typeInferenceTypePredicate.js +++ b/tests/baselines/reference/typeInferenceTypePredicate.js @@ -1,5 +1,5 @@ //// [typeInferenceTypePredicate.ts] -declare function f(predicate: (x: {}) => x is T): T; +declare function f(predicate: (x: unknown) => x is T): T; // 'res' should be of type 'number'. const res = f((n): n is number => true); diff --git a/tests/baselines/reference/typeInferenceTypePredicate.symbols b/tests/baselines/reference/typeInferenceTypePredicate.symbols index 3c2172552ee73..9f4ae468ce9f6 100644 --- a/tests/baselines/reference/typeInferenceTypePredicate.symbols +++ b/tests/baselines/reference/typeInferenceTypePredicate.symbols @@ -1,5 +1,5 @@ === tests/cases/compiler/typeInferenceTypePredicate.ts === -declare function f(predicate: (x: {}) => x is T): T; +declare function f(predicate: (x: unknown) => x is T): T; >f : Symbol(f, Decl(typeInferenceTypePredicate.ts, 0, 0)) >T : Symbol(T, Decl(typeInferenceTypePredicate.ts, 0, 19)) >predicate : Symbol(predicate, Decl(typeInferenceTypePredicate.ts, 0, 22)) diff --git a/tests/baselines/reference/typeInferenceTypePredicate.types b/tests/baselines/reference/typeInferenceTypePredicate.types index dbc1ad6099583..f9a9895997aab 100644 --- a/tests/baselines/reference/typeInferenceTypePredicate.types +++ b/tests/baselines/reference/typeInferenceTypePredicate.types @@ -1,15 +1,15 @@ === tests/cases/compiler/typeInferenceTypePredicate.ts === -declare function f(predicate: (x: {}) => x is T): T; ->f : (predicate: (x: {}) => x is T) => T ->predicate : (x: {}) => x is T ->x : {} +declare function f(predicate: (x: unknown) => x is T): T; +>f : (predicate: (x: unknown) => x is T) => T +>predicate : (x: unknown) => x is T +>x : unknown // 'res' should be of type 'number'. const res = f((n): n is number => true); >res : number >f((n): n is number => true) : number ->f : (predicate: (x: {}) => x is T) => T ->(n): n is number => true : (n: {}) => n is number ->n : {} +>f : (predicate: (x: unknown) => x is T) => T +>(n): n is number => true : (n: unknown) => n is number +>n : unknown >true : true diff --git a/tests/baselines/reference/typeParametersShouldNotBeEqual.errors.txt b/tests/baselines/reference/typeParametersShouldNotBeEqual.errors.txt index c8e48a06898e5..4c438c6f90dc6 100644 --- a/tests/baselines/reference/typeParametersShouldNotBeEqual.errors.txt +++ b/tests/baselines/reference/typeParametersShouldNotBeEqual.errors.txt @@ -3,9 +3,10 @@ tests/cases/compiler/typeParametersShouldNotBeEqual.ts(4,5): error TS2322: Type tests/cases/compiler/typeParametersShouldNotBeEqual.ts(5,5): error TS2322: Type 'Object' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'Object'. The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead? +tests/cases/compiler/typeParametersShouldNotBeEqual.ts(6,5): error TS2322: Type 'T' is not assignable to type 'Object'. -==== tests/cases/compiler/typeParametersShouldNotBeEqual.ts (2 errors) ==== +==== tests/cases/compiler/typeParametersShouldNotBeEqual.ts (3 errors) ==== function ff(x: T, y: U) { var z: Object; x = x; // Ok @@ -19,5 +20,8 @@ tests/cases/compiler/typeParametersShouldNotBeEqual.ts(5,5): error TS2322: Type !!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'Object'. !!! error TS2322: The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead? z = x; // Ok + ~ +!!! error TS2322: Type 'T' is not assignable to type 'Object'. +!!! related TS2797 tests/cases/compiler/typeParametersShouldNotBeEqual.ts:1:13: This type parameter likely needs an `extends object` constraint. } \ No newline at end of file diff --git a/tests/baselines/reference/unknownType1.errors.txt b/tests/baselines/reference/unknownType1.errors.txt index 60856e8ce182b..8c463c6f7c0b3 100644 --- a/tests/baselines/reference/unknownType1.errors.txt +++ b/tests/baselines/reference/unknownType1.errors.txt @@ -26,13 +26,14 @@ tests/cases/conformance/types/unknown/unknownType1.ts(144,29): error TS2698: Spr tests/cases/conformance/types/unknown/unknownType1.ts(150,17): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. tests/cases/conformance/types/unknown/unknownType1.ts(156,14): error TS2700: Rest types may only be created from object types. tests/cases/conformance/types/unknown/unknownType1.ts(162,5): error TS2564: Property 'a' has no initializer and is not definitely assigned in the constructor. +tests/cases/conformance/types/unknown/unknownType1.ts(170,9): error TS2322: Type 'T' is not assignable to type '{}'. tests/cases/conformance/types/unknown/unknownType1.ts(171,9): error TS2322: Type 'U' is not assignable to type '{}'. Type 'unknown' is not assignable to type '{}'. tests/cases/conformance/types/unknown/unknownType1.ts(181,5): error TS2322: Type 'T' is not assignable to type '{}'. Type 'unknown' is not assignable to type '{}'. -==== tests/cases/conformance/types/unknown/unknownType1.ts (27 errors) ==== +==== tests/cases/conformance/types/unknown/unknownType1.ts (28 errors) ==== // In an intersection everything absorbs unknown type T00 = unknown & null; // null @@ -256,6 +257,9 @@ tests/cases/conformance/types/unknown/unknownType1.ts(181,5): error TS2322: Type function f30(t: T, u: U) { let x: {} = t; + ~ +!!! error TS2322: Type 'T' is not assignable to type '{}'. +!!! related TS2797 tests/cases/conformance/types/unknown/unknownType1.ts:169:14: This type parameter likely needs an `extends object` constraint. let y: {} = u; ~ !!! error TS2322: Type 'U' is not assignable to type '{}'. diff --git a/tests/cases/compiler/conditionalTypeDoesntSpinForever.ts b/tests/cases/compiler/conditionalTypeDoesntSpinForever.ts index 9ffbd57ffa17b..703b552411705 100644 --- a/tests/cases/compiler/conditionalTypeDoesntSpinForever.ts +++ b/tests/cases/compiler/conditionalTypeDoesntSpinForever.ts @@ -15,25 +15,25 @@ export enum PubSubRecordIsStoredInRedisAsA { maxMsToWaitBeforePublishing: number; } - type NameFieldConstructor = + type NameFieldConstructor = SO_FAR extends {name: any} ? {} : { name: (t?: TYPE) => BuildPubSubRecordType } - const buildNameFieldConstructor = (soFar: SO_FAR) => ( + const buildNameFieldConstructor = (soFar: SO_FAR) => ( "name" in soFar ? {} : { name: (instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) as BuildPubSubRecordType } ); - type StoredAsConstructor = + type StoredAsConstructor = SO_FAR extends {storedAs: any} ? {} : { storedAsJsonEncodedRedisString: () => BuildPubSubRecordType; storedRedisHash: () => BuildPubSubRecordType; } - const buildStoredAsConstructor = (soFar: SO_FAR) => ( + const buildStoredAsConstructor = (soFar: SO_FAR) => ( "storedAs" in soFar ? {} : { storedAsJsonEncodedRedisString: () => buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as @@ -44,38 +44,38 @@ export enum PubSubRecordIsStoredInRedisAsA { } ); - type IdentifierFieldConstructor = + type IdentifierFieldConstructor = SO_FAR extends {identifier: any} ? {} : SO_FAR extends {record: any} ? { identifier: >(t?: TYPE) => BuildPubSubRecordType } : {} - const buildIdentifierFieldConstructor = (soFar: SO_FAR) => ( + const buildIdentifierFieldConstructor = (soFar: SO_FAR) => ( "identifier" in soFar || (!("record" in soFar)) ? {} : { identifier: (instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) as BuildPubSubRecordType } ); - type RecordFieldConstructor = + type RecordFieldConstructor = SO_FAR extends {record: any} ? {} : { record: (t?: TYPE) => BuildPubSubRecordType } - const buildRecordFieldConstructor = (soFar: SO_FAR) => ( + const buildRecordFieldConstructor = (soFar: SO_FAR) => ( "record" in soFar ? {} : { record: (instance: TYPE = undefined) => buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) as BuildPubSubRecordType } ); - type MaxMsToWaitBeforePublishingFieldConstructor = + type MaxMsToWaitBeforePublishingFieldConstructor = SO_FAR extends {maxMsToWaitBeforePublishing: any} ? {} : { maxMsToWaitBeforePublishing: (t: number) => BuildPubSubRecordType, neverDelayPublishing: () => BuildPubSubRecordType, } - const buildMaxMsToWaitBeforePublishingFieldConstructor = (soFar: SO_FAR): MaxMsToWaitBeforePublishingFieldConstructor => ( + const buildMaxMsToWaitBeforePublishingFieldConstructor = (soFar: SO_FAR): MaxMsToWaitBeforePublishingFieldConstructor => ( "maxMsToWaitBeforePublishing" in soFar ? {} : { maxMsToWaitBeforePublishing: (instance: number = 0) => buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType, @@ -84,14 +84,14 @@ export enum PubSubRecordIsStoredInRedisAsA { } ) as MaxMsToWaitBeforePublishingFieldConstructor; - type TypeConstructor = + type TypeConstructor = SO_FAR extends {identifier: any, record: any, maxMsToWaitBeforePublishing: number, storedAs: PubSubRecordIsStoredInRedisAsA} ? { type: SO_FAR, fields: Set, hasField: (fieldName: string | number | symbol) => fieldName is keyof SO_FAR } : {} - const buildType = (soFar: SO_FAR) => ( + const buildType = (soFar: SO_FAR) => ( "identifier" in soFar && "object" in soFar && "maxMsToWaitBeforePublishing" in soFar && "PubSubRecordIsStoredInRedisAsA" in soFar ? {} : { type: soFar, fields: () => new Set(Object.keys(soFar) as (keyof SO_FAR)[]), @@ -99,7 +99,7 @@ export enum PubSubRecordIsStoredInRedisAsA { } ); - type BuildPubSubRecordType = + type BuildPubSubRecordType = NameFieldConstructor & IdentifierFieldConstructor & RecordFieldConstructor & @@ -107,7 +107,7 @@ export enum PubSubRecordIsStoredInRedisAsA { MaxMsToWaitBeforePublishingFieldConstructor & TypeConstructor - const buildPubSubRecordType = (soFar: SO_FAR) => Object.assign( + const buildPubSubRecordType = (soFar: SO_FAR) => Object.assign( {}, buildNameFieldConstructor(soFar), buildIdentifierFieldConstructor(soFar), diff --git a/tests/cases/compiler/declarationEmitExpressionInExtends5.ts b/tests/cases/compiler/declarationEmitExpressionInExtends5.ts index 5057ade7570d9..1803d206fbbf0 100644 --- a/tests/cases/compiler/declarationEmitExpressionInExtends5.ts +++ b/tests/cases/compiler/declarationEmitExpressionInExtends5.ts @@ -13,7 +13,7 @@ namespace Test { } - export function getClass() : new() => T + export function getClass() : new() => T { return SomeClass as (new() => T); } diff --git a/tests/cases/compiler/genericPrototypeProperty3.ts b/tests/cases/compiler/genericPrototypeProperty3.ts index 2349a44277d9d..bee9e120b9bce 100644 --- a/tests/cases/compiler/genericPrototypeProperty3.ts +++ b/tests/cases/compiler/genericPrototypeProperty3.ts @@ -1,5 +1,5 @@ class BaseEvent { - target: {}; + target: unknown; } class MyEvent extends BaseEvent { // T is instantiated to any in the prototype, which is assignable to {} diff --git a/tests/cases/compiler/typeInferenceTypePredicate.ts b/tests/cases/compiler/typeInferenceTypePredicate.ts index 039baec34f23e..e926d3b4e073e 100644 --- a/tests/cases/compiler/typeInferenceTypePredicate.ts +++ b/tests/cases/compiler/typeInferenceTypePredicate.ts @@ -1,3 +1,3 @@ -declare function f(predicate: (x: {}) => x is T): T; +declare function f(predicate: (x: unknown) => x is T): T; // 'res' should be of type 'number'. const res = f((n): n is number => true); diff --git a/tests/cases/conformance/types/mapped/isomorphicMappedTypeInference.ts b/tests/cases/conformance/types/mapped/isomorphicMappedTypeInference.ts index 031cf840d33f4..4cc2d08be6c6b 100644 --- a/tests/cases/conformance/types/mapped/isomorphicMappedTypeInference.ts +++ b/tests/cases/conformance/types/mapped/isomorphicMappedTypeInference.ts @@ -26,7 +26,7 @@ function boxify(obj: T): Boxified { return result; } -function unboxify(obj: Boxified): T { +function unboxify(obj: Boxified): T { let result = {} as T; for (let k in obj) { result[k] = unbox(obj[k]);