From 1ac0709eda84b1ccd53a7ea6d3223eaa61ad1470 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 2 May 2022 21:08:34 +0000 Subject: [PATCH 1/2] Revert a change around allowing unconstrained type parameters to '{}'. --- src/compiler/checker.ts | 9 +++------ src/compiler/diagnosticMessages.json | 4 ---- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5efefc51d244d..5a1f6f440fe7e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18772,9 +18772,6 @@ namespace ts { return; } reportRelationError(headMessage, source, target); - if (strictNullChecks && source.flags & TypeFlags.TypeVariable && source.symbol?.declarations?.[0] && !getConstraintOfType(source as TypeVariable) && isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) { - associateRelatedInfo(createDiagnosticForNode(source.symbol.declarations[0], Diagnostics.This_type_parameter_probably_needs_an_extends_object_constraint)); - } } function traceUnionsOrIntersectionsTooLarge(source: Type, target: Type): void { @@ -19565,7 +19562,7 @@ namespace ts { // IndexedAccess comparisons are handled above in the `targetFlags & TypeFlage.IndexedAccess` branch if (!(sourceFlags & TypeFlags.IndexedAccess && targetFlags & TypeFlags.IndexedAccess)) { const constraint = getConstraintOfType(source as TypeVariable); - if (!strictNullChecks && (!constraint || (sourceFlags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.Any))) { + if (!constraint || (sourceFlags & 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), RecursionFlags.Both)) { resetErrorInfo(saveErrorInfo); @@ -19573,12 +19570,12 @@ namespace ts { } } // 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 (constraint && (result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState))) { + else if (result = isRelatedTo(constraint, target, RecursionFlags.Source, /*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 (constraint && (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, RecursionFlags.Source, reportErrors && !(targetFlags & sourceFlags & TypeFlags.TypeParameter), /*headMessage*/ undefined, intersectionState))) { + else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, RecursionFlags.Source, reportErrors && !(targetFlags & sourceFlags & TypeFlags.TypeParameter), /*headMessage*/ undefined, intersectionState)) { resetErrorInfo(saveErrorInfo); return result; } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 22c923012aaeb..207b23d70135a 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1506,10 +1506,6 @@ "category": "Error", "code": 2207 }, - "This type parameter probably needs an `extends object` constraint.": { - "category": "Error", - "code": 2208 - }, "Duplicate identifier '{0}'.": { "category": "Error", From 92e2229137eb4e78d1faee56f23a6a614d06e64f Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 2 May 2022 21:08:44 +0000 Subject: [PATCH 2/2] Accepted baselines. --- ...UnboundedTypeParamAssignability.errors.txt | 10 +- .../keyofAndIndexedAccess.errors.txt | 709 ------------------ .../mappedTypesAndObjects.errors.txt | 54 -- .../tsxNotUsingApparentTypeOfSFC.errors.txt | 22 +- .../reference/unknownType1.errors.txt | 6 +- 5 files changed, 3 insertions(+), 798 deletions(-) delete mode 100644 tests/baselines/reference/keyofAndIndexedAccess.errors.txt delete mode 100644 tests/baselines/reference/mappedTypesAndObjects.errors.txt diff --git a/tests/baselines/reference/genericUnboundedTypeParamAssignability.errors.txt b/tests/baselines/reference/genericUnboundedTypeParamAssignability.errors.txt index 6d7b87ebd3351..b00dfc3c32857 100644 --- a/tests/baselines/reference/genericUnboundedTypeParamAssignability.errors.txt +++ b/tests/baselines/reference/genericUnboundedTypeParamAssignability.errors.txt @@ -1,10 +1,8 @@ tests/cases/compiler/genericUnboundedTypeParamAssignability.ts(2,5): error TS2339: Property 'toString' does not exist on type 'T'. -tests/cases/compiler/genericUnboundedTypeParamAssignability.ts(15,6): error TS2345: Argument of type 'T' is not assignable to parameter of type '{}'. -tests/cases/compiler/genericUnboundedTypeParamAssignability.ts(16,6): error TS2345: Argument of type 'T' is not assignable to parameter of type 'Record'. tests/cases/compiler/genericUnboundedTypeParamAssignability.ts(17,5): error TS2339: Property 'toString' does not exist on type 'T'. -==== tests/cases/compiler/genericUnboundedTypeParamAssignability.ts (4 errors) ==== +==== tests/cases/compiler/genericUnboundedTypeParamAssignability.ts (2 errors) ==== function f1(o: T) { o.toString(); // error ~~~~~~~~ @@ -22,13 +20,7 @@ tests/cases/compiler/genericUnboundedTypeParamAssignability.ts(17,5): error TS23 function user(t: T) { f1(t); f2(t); // error in strict, unbounded T doesn't satisfy the constraint - ~ -!!! error TS2345: Argument of type 'T' is not assignable to parameter of type '{}'. -!!! related TS2208 tests/cases/compiler/genericUnboundedTypeParamAssignability.ts:13:15: This type parameter probably needs an `extends object` constraint. f3(t); // error in strict, unbounded T doesn't satisfy the constraint - ~ -!!! error TS2345: Argument of type 'T' is not assignable to parameter of type 'Record'. -!!! related TS2208 tests/cases/compiler/genericUnboundedTypeParamAssignability.ts:13:15: This type parameter probably needs an `extends object` constraint. t.toString(); // error, for the same reason as f1() ~~~~~~~~ !!! error TS2339: Property 'toString' does not exist on type 'T'. diff --git a/tests/baselines/reference/keyofAndIndexedAccess.errors.txt b/tests/baselines/reference/keyofAndIndexedAccess.errors.txt deleted file mode 100644 index f5c436bbf1dc2..0000000000000 --- a/tests/baselines/reference/keyofAndIndexedAccess.errors.txt +++ /dev/null @@ -1,709 +0,0 @@ -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'. -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'. -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'. -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'. -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'. - - -==== 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 TS2208 tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts:314:14: This type parameter probably 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'. -!!! related TS2208 tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts:321:14: This type parameter probably 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'. - 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'. - } - - // 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'. - 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'. - } - } - - // 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/mappedTypesAndObjects.errors.txt b/tests/baselines/reference/mappedTypesAndObjects.errors.txt deleted file mode 100644 index c32fc58b370e7..0000000000000 --- a/tests/baselines/reference/mappedTypesAndObjects.errors.txt +++ /dev/null @@ -1,54 +0,0 @@ -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 TS2208 tests/cases/conformance/types/mapped/mappedTypesAndObjects.ts:25:14: This type parameter probably 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/tsxNotUsingApparentTypeOfSFC.errors.txt b/tests/baselines/reference/tsxNotUsingApparentTypeOfSFC.errors.txt index a967c92e555ac..81231a345627b 100644 --- a/tests/baselines/reference/tsxNotUsingApparentTypeOfSFC.errors.txt +++ b/tests/baselines/reference/tsxNotUsingApparentTypeOfSFC.errors.txt @@ -5,17 +5,9 @@ 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

'. -==== tests/cases/compiler/tsxNotUsingApparentTypeOfSFC.tsx (4 errors) ==== +==== tests/cases/compiler/tsxNotUsingApparentTypeOfSFC.tsx (2 errors) ==== /// import React from 'react'; @@ -42,17 +34,5 @@ tests/cases/compiler/tsxNotUsingApparentTypeOfSFC.tsx(18,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 TS2208 tests/cases/compiler/tsxNotUsingApparentTypeOfSFC.tsx:5:15: This type parameter probably 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

'. -!!! related TS2208 tests/cases/compiler/tsxNotUsingApparentTypeOfSFC.tsx:5:15: This type parameter probably 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 39d7a1feb5255..138fff847cc88 100644 --- a/tests/baselines/reference/unknownType1.errors.txt +++ b/tests/baselines/reference/unknownType1.errors.txt @@ -25,14 +25,13 @@ 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 (28 errors) ==== +==== tests/cases/conformance/types/unknown/unknownType1.ts (27 errors) ==== // In an intersection everything absorbs unknown type T00 = unknown & null; // null @@ -255,9 +254,6 @@ 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 TS2208 tests/cases/conformance/types/unknown/unknownType1.ts:169:14: This type parameter probably needs an `extends object` constraint. let y: {} = u; ~ !!! error TS2322: Type 'U' is not assignable to type '{}'.