From 4a5dfd0e4038379bc179762a184ca31560bd9470 Mon Sep 17 00:00:00 2001 From: Andrea Simone Costa Date: Thu, 21 Sep 2023 10:40:51 +0200 Subject: [PATCH 1/8] support intersection constraint, add test --- src/compiler/checker.ts | 4 +- .../reference/revertedIntersection.errors.txt | 124 +++++++++ .../reference/revertedIntersection.js | 158 +++++++++++ .../reference/revertedIntersection.symbols | 257 ++++++++++++++++++ .../reference/revertedIntersection.types | 251 +++++++++++++++++ tests/cases/compiler/revertedIntersection.ts | 92 +++++++ 6 files changed, 884 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/revertedIntersection.errors.txt create mode 100644 tests/baselines/reference/revertedIntersection.js create mode 100644 tests/baselines/reference/revertedIntersection.symbols create mode 100644 tests/baselines/reference/revertedIntersection.types create mode 100644 tests/cases/compiler/revertedIntersection.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 40d4f07ffd325..cdba5f2a0e5e5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25343,9 +25343,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function inferToMappedType(source: Type, target: MappedType, constraintType: Type): boolean { - if (constraintType.flags & TypeFlags.Union) { + if ((constraintType.flags & TypeFlags.Union) || (constraintType.flags & TypeFlags.Intersection)) { let result = false; - for (const type of (constraintType as UnionType).types) { + for (const type of (constraintType as (UnionType | IntersectionType)).types) { result = inferToMappedType(source, target, type) || result; } return result; diff --git a/tests/baselines/reference/revertedIntersection.errors.txt b/tests/baselines/reference/revertedIntersection.errors.txt new file mode 100644 index 0000000000000..09c14e18f81c8 --- /dev/null +++ b/tests/baselines/reference/revertedIntersection.errors.txt @@ -0,0 +1,124 @@ +revertedIntersection.ts(19,7): error TS2322: Type '"bar"' is not assignable to type '"foo"'. +revertedIntersection.ts(32,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ entry: "foo"; states: { a: { entry: "foo"; }; }; }'. +revertedIntersection.ts(43,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. +revertedIntersection.ts(60,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. + '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. +revertedIntersection.ts(64,49): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. +revertedIntersection.ts(70,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. + Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. + '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. +revertedIntersection.ts(75,36): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. +revertedIntersection.ts(88,12): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. + + +==== revertedIntersection.ts (8 errors) ==== + type StateConfig = { + entry?: TAction + states?: Record>; + }; + + type StateSchema = { + states?: Record; + }; + + declare function createMachine< + TConfig extends StateConfig, + TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, + >(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; + + const inferredParams1 = createMachine({ + entry: "foo", + states: { + a: { + entry: "bar", + ~~~~~ +!!! error TS2322: Type '"bar"' is not assignable to type '"foo"'. +!!! related TS6500 revertedIntersection.ts:2:3: The expected type comes from property 'entry' which is declared here on type 'StateConfig<"foo">' + }, + }, + extra: 12, + }); + + const inferredParams2 = createMachine({ + entry: "foo", + states: { + a: { + entry: "foo", + }, + }, + extra: 12, + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ entry: "foo"; states: { a: { entry: "foo"; }; }; }'. + }); + + + // ----------------------------------------------------------------------------------------- + + const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; + + const checked = checkType<{x: number, y: string}>()({ + x: 1 as number, + y: "y", + z: "z", // undesirable property z is *not* allowed + ~ +!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. + }); + + checked; + // ^? + + // ----------------------------------------------------------------------------------------- + + interface Stuff { + field: number; + anotherField: string; + } + + function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { + if(Math.random() > 0.5) { + return s as T + } else { + return s + ~~~~~~ +!!! error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. +!!! error TS2322: '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. + } + } + + doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. + + function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { + if(Math.random() > 0.5) { + return arr as T[] + } else { + return arr + ~~~~~~ +!!! error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. +!!! error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. +!!! error TS2322: '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. + } + } + + doStuffWithStuffArr([ + { field: 1, anotherField: 'a', extra: 123 }, + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. + ]) + + // ----------------------------------------------------------------------------------------- + + type XNumber = { x: number } + + declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; + + function bar(props: {x: number, y: string}) { + return foo(props); // no error because lack of excess property check by design + } + + foo({x: 1, y: 'foo'}); + ~ +!!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. + + foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design \ No newline at end of file diff --git a/tests/baselines/reference/revertedIntersection.js b/tests/baselines/reference/revertedIntersection.js new file mode 100644 index 0000000000000..4eb7df60cbdd7 --- /dev/null +++ b/tests/baselines/reference/revertedIntersection.js @@ -0,0 +1,158 @@ +//// [tests/cases/compiler/revertedIntersection.ts] //// + +//// [revertedIntersection.ts] +type StateConfig = { + entry?: TAction + states?: Record>; +}; + +type StateSchema = { + states?: Record; +}; + +declare function createMachine< + TConfig extends StateConfig, + TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, +>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; + +const inferredParams1 = createMachine({ + entry: "foo", + states: { + a: { + entry: "bar", + }, + }, + extra: 12, +}); + +const inferredParams2 = createMachine({ + entry: "foo", + states: { + a: { + entry: "foo", + }, + }, + extra: 12, +}); + + +// ----------------------------------------------------------------------------------------- + +const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; + +const checked = checkType<{x: number, y: string}>()({ + x: 1 as number, + y: "y", + z: "z", // undesirable property z is *not* allowed +}); + +checked; + // ^? + +// ----------------------------------------------------------------------------------------- + +interface Stuff { + field: number; + anotherField: string; +} + +function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { + if(Math.random() > 0.5) { + return s as T + } else { + return s + } +} + +doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) + +function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { + if(Math.random() > 0.5) { + return arr as T[] + } else { + return arr + } +} + +doStuffWithStuffArr([ + { field: 1, anotherField: 'a', extra: 123 }, +]) + +// ----------------------------------------------------------------------------------------- + +type XNumber = { x: number } + +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; + +function bar(props: {x: number, y: string}) { + return foo(props); // no error because lack of excess property check by design +} + +foo({x: 1, y: 'foo'}); + +foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design + +//// [revertedIntersection.js] +"use strict"; +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var inferredParams1 = createMachine({ + entry: "foo", + states: { + a: { + entry: "bar", + }, + }, + extra: 12, +}); +var inferredParams2 = createMachine({ + entry: "foo", + states: { + a: { + entry: "foo", + }, + }, + extra: 12, +}); +// ----------------------------------------------------------------------------------------- +var checkType = function () { return function (value) { return value; }; }; +var checked = checkType()({ + x: 1, + y: "y", + z: "z", // undesirable property z is *not* allowed +}); +checked; +function doStuffWithStuff(s) { + if (Math.random() > 0.5) { + return s; + } + else { + return s; + } +} +doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }); +function doStuffWithStuffArr(arr) { + if (Math.random() > 0.5) { + return arr; + } + else { + return arr; + } +} +doStuffWithStuffArr([ + { field: 1, anotherField: 'a', extra: 123 }, +]); +function bar(props) { + return foo(props); // no error because lack of excess property check by design +} +foo({ x: 1, y: 'foo' }); +foo(__assign({ x: 1, y: 'foo' })); // no error because lack of excess property check by design diff --git a/tests/baselines/reference/revertedIntersection.symbols b/tests/baselines/reference/revertedIntersection.symbols new file mode 100644 index 0000000000000..c134e304df02a --- /dev/null +++ b/tests/baselines/reference/revertedIntersection.symbols @@ -0,0 +1,257 @@ +//// [tests/cases/compiler/revertedIntersection.ts] //// + +=== revertedIntersection.ts === +type StateConfig = { +>StateConfig : Symbol(StateConfig, Decl(revertedIntersection.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(revertedIntersection.ts, 0, 17)) + + entry?: TAction +>entry : Symbol(entry, Decl(revertedIntersection.ts, 0, 44)) +>TAction : Symbol(TAction, Decl(revertedIntersection.ts, 0, 17)) + + states?: Record>; +>states : Symbol(states, Decl(revertedIntersection.ts, 1, 17)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>StateConfig : Symbol(StateConfig, Decl(revertedIntersection.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(revertedIntersection.ts, 0, 17)) + +}; + +type StateSchema = { +>StateSchema : Symbol(StateSchema, Decl(revertedIntersection.ts, 3, 2)) + + states?: Record; +>states : Symbol(states, Decl(revertedIntersection.ts, 5, 20)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>StateSchema : Symbol(StateSchema, Decl(revertedIntersection.ts, 3, 2)) + +}; + +declare function createMachine< +>createMachine : Symbol(createMachine, Decl(revertedIntersection.ts, 7, 2)) + + TConfig extends StateConfig, +>TConfig : Symbol(TConfig, Decl(revertedIntersection.ts, 9, 31)) +>StateConfig : Symbol(StateConfig, Decl(revertedIntersection.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(revertedIntersection.ts, 10, 39)) + + TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, +>TAction : Symbol(TAction, Decl(revertedIntersection.ts, 10, 39)) +>TConfig : Symbol(TConfig, Decl(revertedIntersection.ts, 9, 31)) +>TConfig : Symbol(TConfig, Decl(revertedIntersection.ts, 9, 31)) + +>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; +>config : Symbol(config, Decl(revertedIntersection.ts, 12, 2)) +>K : Symbol(K, Decl(revertedIntersection.ts, 12, 13)) +>TConfig : Symbol(TConfig, Decl(revertedIntersection.ts, 9, 31)) +>StateConfig : Symbol(StateConfig, Decl(revertedIntersection.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(revertedIntersection.ts, 10, 39)) +>TConfig : Symbol(TConfig, Decl(revertedIntersection.ts, 9, 31)) +>K : Symbol(K, Decl(revertedIntersection.ts, 12, 13)) +>TAction : Symbol(TAction, Decl(revertedIntersection.ts, 10, 39)) +>TConfig : Symbol(TConfig, Decl(revertedIntersection.ts, 9, 31)) + +const inferredParams1 = createMachine({ +>inferredParams1 : Symbol(inferredParams1, Decl(revertedIntersection.ts, 14, 5)) +>createMachine : Symbol(createMachine, Decl(revertedIntersection.ts, 7, 2)) + + entry: "foo", +>entry : Symbol(entry, Decl(revertedIntersection.ts, 14, 39)) + + states: { +>states : Symbol(states, Decl(revertedIntersection.ts, 15, 15)) + + a: { +>a : Symbol(a, Decl(revertedIntersection.ts, 16, 11)) + + entry: "bar", +>entry : Symbol(entry, Decl(revertedIntersection.ts, 17, 8)) + + }, + }, + extra: 12, +>extra : Symbol(extra, Decl(revertedIntersection.ts, 20, 4)) + +}); + +const inferredParams2 = createMachine({ +>inferredParams2 : Symbol(inferredParams2, Decl(revertedIntersection.ts, 24, 5)) +>createMachine : Symbol(createMachine, Decl(revertedIntersection.ts, 7, 2)) + + entry: "foo", +>entry : Symbol(entry, Decl(revertedIntersection.ts, 24, 39)) + + states: { +>states : Symbol(states, Decl(revertedIntersection.ts, 25, 15)) + + a: { +>a : Symbol(a, Decl(revertedIntersection.ts, 26, 11)) + + entry: "foo", +>entry : Symbol(entry, Decl(revertedIntersection.ts, 27, 8)) + + }, + }, + extra: 12, +>extra : Symbol(extra, Decl(revertedIntersection.ts, 30, 4)) + +}); + + +// ----------------------------------------------------------------------------------------- + +const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; +>checkType : Symbol(checkType, Decl(revertedIntersection.ts, 37, 5)) +>T : Symbol(T, Decl(revertedIntersection.ts, 37, 19)) +>U : Symbol(U, Decl(revertedIntersection.ts, 37, 28)) +>T : Symbol(T, Decl(revertedIntersection.ts, 37, 19)) +>value : Symbol(value, Decl(revertedIntersection.ts, 37, 41)) +>K : Symbol(K, Decl(revertedIntersection.ts, 37, 51)) +>U : Symbol(U, Decl(revertedIntersection.ts, 37, 28)) +>T : Symbol(T, Decl(revertedIntersection.ts, 37, 19)) +>U : Symbol(U, Decl(revertedIntersection.ts, 37, 28)) +>K : Symbol(K, Decl(revertedIntersection.ts, 37, 51)) +>value : Symbol(value, Decl(revertedIntersection.ts, 37, 41)) + +const checked = checkType<{x: number, y: string}>()({ +>checked : Symbol(checked, Decl(revertedIntersection.ts, 39, 5)) +>checkType : Symbol(checkType, Decl(revertedIntersection.ts, 37, 5)) +>x : Symbol(x, Decl(revertedIntersection.ts, 39, 27)) +>y : Symbol(y, Decl(revertedIntersection.ts, 39, 37)) + + x: 1 as number, +>x : Symbol(x, Decl(revertedIntersection.ts, 39, 53)) + + y: "y", +>y : Symbol(y, Decl(revertedIntersection.ts, 40, 17)) + + z: "z", // undesirable property z is *not* allowed +>z : Symbol(z, Decl(revertedIntersection.ts, 41, 9)) + +}); + +checked; +>checked : Symbol(checked, Decl(revertedIntersection.ts, 39, 5)) + + // ^? + +// ----------------------------------------------------------------------------------------- + +interface Stuff { +>Stuff : Symbol(Stuff, Decl(revertedIntersection.ts, 45, 8)) + + field: number; +>field : Symbol(Stuff.field, Decl(revertedIntersection.ts, 50, 17)) + + anotherField: string; +>anotherField : Symbol(Stuff.anotherField, Decl(revertedIntersection.ts, 51, 18)) +} + +function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { +>doStuffWithStuff : Symbol(doStuffWithStuff, Decl(revertedIntersection.ts, 53, 1)) +>T : Symbol(T, Decl(revertedIntersection.ts, 55, 26)) +>Stuff : Symbol(Stuff, Decl(revertedIntersection.ts, 45, 8)) +>s : Symbol(s, Decl(revertedIntersection.ts, 55, 43)) +>K : Symbol(K, Decl(revertedIntersection.ts, 55, 49)) +>T : Symbol(T, Decl(revertedIntersection.ts, 55, 26)) +>Stuff : Symbol(Stuff, Decl(revertedIntersection.ts, 45, 8)) +>T : Symbol(T, Decl(revertedIntersection.ts, 55, 26)) +>K : Symbol(K, Decl(revertedIntersection.ts, 55, 49)) +>T : Symbol(T, Decl(revertedIntersection.ts, 55, 26)) + + if(Math.random() > 0.5) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + return s as T +>s : Symbol(s, Decl(revertedIntersection.ts, 55, 43)) +>T : Symbol(T, Decl(revertedIntersection.ts, 55, 26)) + + } else { + return s +>s : Symbol(s, Decl(revertedIntersection.ts, 55, 43)) + } +} + +doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) +>doStuffWithStuff : Symbol(doStuffWithStuff, Decl(revertedIntersection.ts, 53, 1)) +>field : Symbol(field, Decl(revertedIntersection.ts, 63, 18)) +>anotherField : Symbol(anotherField, Decl(revertedIntersection.ts, 63, 28)) +>extra : Symbol(extra, Decl(revertedIntersection.ts, 63, 47)) + +function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { +>doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(revertedIntersection.ts, 63, 61)) +>T : Symbol(T, Decl(revertedIntersection.ts, 65, 29)) +>Stuff : Symbol(Stuff, Decl(revertedIntersection.ts, 45, 8)) +>arr : Symbol(arr, Decl(revertedIntersection.ts, 65, 46)) +>K : Symbol(K, Decl(revertedIntersection.ts, 65, 54)) +>T : Symbol(T, Decl(revertedIntersection.ts, 65, 29)) +>Stuff : Symbol(Stuff, Decl(revertedIntersection.ts, 45, 8)) +>T : Symbol(T, Decl(revertedIntersection.ts, 65, 29)) +>K : Symbol(K, Decl(revertedIntersection.ts, 65, 54)) +>T : Symbol(T, Decl(revertedIntersection.ts, 65, 29)) + + if(Math.random() > 0.5) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + return arr as T[] +>arr : Symbol(arr, Decl(revertedIntersection.ts, 65, 46)) +>T : Symbol(T, Decl(revertedIntersection.ts, 65, 29)) + + } else { + return arr +>arr : Symbol(arr, Decl(revertedIntersection.ts, 65, 46)) + } +} + +doStuffWithStuffArr([ +>doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(revertedIntersection.ts, 63, 61)) + + { field: 1, anotherField: 'a', extra: 123 }, +>field : Symbol(field, Decl(revertedIntersection.ts, 74, 5)) +>anotherField : Symbol(anotherField, Decl(revertedIntersection.ts, 74, 15)) +>extra : Symbol(extra, Decl(revertedIntersection.ts, 74, 34)) + +]) + +// ----------------------------------------------------------------------------------------- + +type XNumber = { x: number } +>XNumber : Symbol(XNumber, Decl(revertedIntersection.ts, 75, 2)) +>x : Symbol(x, Decl(revertedIntersection.ts, 79, 16)) + +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; +>foo : Symbol(foo, Decl(revertedIntersection.ts, 79, 28)) +>T : Symbol(T, Decl(revertedIntersection.ts, 81, 21)) +>XNumber : Symbol(XNumber, Decl(revertedIntersection.ts, 75, 2)) +>props : Symbol(props, Decl(revertedIntersection.ts, 81, 40)) +>K : Symbol(K, Decl(revertedIntersection.ts, 81, 49)) +>T : Symbol(T, Decl(revertedIntersection.ts, 81, 21)) +>XNumber : Symbol(XNumber, Decl(revertedIntersection.ts, 75, 2)) +>T : Symbol(T, Decl(revertedIntersection.ts, 81, 21)) +>K : Symbol(K, Decl(revertedIntersection.ts, 81, 49)) + +function bar(props: {x: number, y: string}) { +>bar : Symbol(bar, Decl(revertedIntersection.ts, 81, 93)) +>props : Symbol(props, Decl(revertedIntersection.ts, 83, 13)) +>x : Symbol(x, Decl(revertedIntersection.ts, 83, 21)) +>y : Symbol(y, Decl(revertedIntersection.ts, 83, 31)) + + return foo(props); // no error because lack of excess property check by design +>foo : Symbol(foo, Decl(revertedIntersection.ts, 79, 28)) +>props : Symbol(props, Decl(revertedIntersection.ts, 83, 13)) +} + +foo({x: 1, y: 'foo'}); +>foo : Symbol(foo, Decl(revertedIntersection.ts, 79, 28)) +>x : Symbol(x, Decl(revertedIntersection.ts, 87, 5)) +>y : Symbol(y, Decl(revertedIntersection.ts, 87, 10)) + +foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design +>foo : Symbol(foo, Decl(revertedIntersection.ts, 79, 28)) +>x : Symbol(x, Decl(revertedIntersection.ts, 89, 9)) +>y : Symbol(y, Decl(revertedIntersection.ts, 89, 14)) + diff --git a/tests/baselines/reference/revertedIntersection.types b/tests/baselines/reference/revertedIntersection.types new file mode 100644 index 0000000000000..af5d27503dfe0 --- /dev/null +++ b/tests/baselines/reference/revertedIntersection.types @@ -0,0 +1,251 @@ +//// [tests/cases/compiler/revertedIntersection.ts] //// + +=== revertedIntersection.ts === +type StateConfig = { +>StateConfig : StateConfig + + entry?: TAction +>entry : TAction | undefined + + states?: Record>; +>states : Record> | undefined + +}; + +type StateSchema = { +>StateSchema : { states?: Record | undefined; } + + states?: Record; +>states : Record | undefined + +}; + +declare function createMachine< +>createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] + + TConfig extends StateConfig, + TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, +>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; +>config : { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; } + +const inferredParams1 = createMachine({ +>inferredParams1 : ["foo", StateConfig<"foo">] +>createMachine({ entry: "foo", states: { a: { entry: "bar", }, }, extra: 12,}) : ["foo", StateConfig<"foo">] +>createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] +>{ entry: "foo", states: { a: { entry: "bar", }, }, extra: 12,} : { entry: "foo"; states: { a: { entry: "bar"; }; }; extra: number; } + + entry: "foo", +>entry : "foo" +>"foo" : "foo" + + states: { +>states : { a: { entry: "bar"; }; } +>{ a: { entry: "bar", }, } : { a: { entry: "bar"; }; } + + a: { +>a : { entry: "bar"; } +>{ entry: "bar", } : { entry: "bar"; } + + entry: "bar", +>entry : "bar" +>"bar" : "bar" + + }, + }, + extra: 12, +>extra : number +>12 : 12 + +}); + +const inferredParams2 = createMachine({ +>inferredParams2 : ["foo", { entry: "foo"; states: { a: { entry: "foo"; }; }; extra: number; }] +>createMachine({ entry: "foo", states: { a: { entry: "foo", }, }, extra: 12,}) : ["foo", { entry: "foo"; states: { a: { entry: "foo"; }; }; extra: number; }] +>createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] +>{ entry: "foo", states: { a: { entry: "foo", }, }, extra: 12,} : { entry: "foo"; states: { a: { entry: "foo"; }; }; extra: number; } + + entry: "foo", +>entry : "foo" +>"foo" : "foo" + + states: { +>states : { a: { entry: "foo"; }; } +>{ a: { entry: "foo", }, } : { a: { entry: "foo"; }; } + + a: { +>a : { entry: "foo"; } +>{ entry: "foo", } : { entry: "foo"; } + + entry: "foo", +>entry : "foo" +>"foo" : "foo" + + }, + }, + extra: 12, +>extra : number +>12 : 12 + +}); + + +// ----------------------------------------------------------------------------------------- + +const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; +>checkType : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>() => (value: { [K in keyof U & keyof T]: U[K] }) => value : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>(value: { [K in keyof U & keyof T]: U[K] }) => value : (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>value : { [K in keyof U & keyof T]: U[K]; } +>value : { [K in keyof U & keyof T]: U[K]; } + +const checked = checkType<{x: number, y: string}>()({ +>checked : { x: number; y: "y"; } +>checkType<{x: number, y: string}>()({ x: 1 as number, y: "y", z: "z", // undesirable property z is *not* allowed}) : { x: number; y: "y"; } +>checkType<{x: number, y: string}>() : (value: { [K in keyof U & ("x" | "y")]: U[K]; }) => { [K in keyof U & ("x" | "y")]: U[K]; } +>checkType : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>x : number +>y : string +>{ x: 1 as number, y: "y", z: "z", // undesirable property z is *not* allowed} : { x: number; y: "y"; z: string; } + + x: 1 as number, +>x : number +>1 as number : number +>1 : 1 + + y: "y", +>y : "y" +>"y" : "y" + + z: "z", // undesirable property z is *not* allowed +>z : string +>"z" : "z" + +}); + +checked; +>checked : { x: number; y: "y"; } + + // ^? + +// ----------------------------------------------------------------------------------------- + +interface Stuff { + field: number; +>field : number + + anotherField: string; +>anotherField : string +} + +function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { +>doStuffWithStuff : (s: { [K in keyof T & keyof Stuff]: T[K]; }) => T +>s : { [K in keyof T & keyof Stuff]: T[K]; } + + if(Math.random() > 0.5) { +>Math.random() > 0.5 : boolean +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>0.5 : 0.5 + + return s as T +>s as T : T +>s : { [K in keyof T & keyof Stuff]: T[K]; } + + } else { + return s +>s : { [K in keyof T & keyof Stuff]: T[K]; } + } +} + +doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) +>doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) : { field: 1; anotherField: "a"; extra: number; } +>doStuffWithStuff : (s: { [K in keyof T & keyof Stuff]: T[K]; }) => T +>{ field: 1, anotherField: 'a', extra: 123 } : { field: 1; anotherField: "a"; extra: number; } +>field : 1 +>1 : 1 +>anotherField : "a" +>'a' : "a" +>extra : number +>123 : 123 + +function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { +>doStuffWithStuffArr : (arr: { [K in keyof T & keyof Stuff]: T[K]; }[]) => T[] +>arr : { [K in keyof T & keyof Stuff]: T[K]; }[] + + if(Math.random() > 0.5) { +>Math.random() > 0.5 : boolean +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>0.5 : 0.5 + + return arr as T[] +>arr as T[] : T[] +>arr : { [K in keyof T & keyof Stuff]: T[K]; }[] + + } else { + return arr +>arr : { [K in keyof T & keyof Stuff]: T[K]; }[] + } +} + +doStuffWithStuffArr([ +>doStuffWithStuffArr([ { field: 1, anotherField: 'a', extra: 123 },]) : { field: 1; anotherField: "a"; extra: number; }[] +>doStuffWithStuffArr : (arr: { [K in keyof T & keyof Stuff]: T[K]; }[]) => T[] +>[ { field: 1, anotherField: 'a', extra: 123 },] : { field: 1; anotherField: "a"; extra: number; }[] + + { field: 1, anotherField: 'a', extra: 123 }, +>{ field: 1, anotherField: 'a', extra: 123 } : { field: 1; anotherField: "a"; extra: number; } +>field : 1 +>1 : 1 +>anotherField : "a" +>'a' : "a" +>extra : number +>123 : 123 + +]) + +// ----------------------------------------------------------------------------------------- + +type XNumber = { x: number } +>XNumber : { x: number; } +>x : number + +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => void +>props : { [K in keyof T & "x"]: T[K]; } + +function bar(props: {x: number, y: string}) { +>bar : (props: { x: number; y: string;}) => void +>props : { x: number; y: string; } +>x : number +>y : string + + return foo(props); // no error because lack of excess property check by design +>foo(props) : void +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => void +>props : { x: number; y: string; } +} + +foo({x: 1, y: 'foo'}); +>foo({x: 1, y: 'foo'}) : void +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => void +>{x: 1, y: 'foo'} : { x: 1; y: string; } +>x : 1 +>1 : 1 +>y : string +>'foo' : "foo" + +foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design +>foo({...{x: 1, y: 'foo'}}) : void +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => void +>{...{x: 1, y: 'foo'}} : { x: 1; y: string; } +>{x: 1, y: 'foo'} : { x: 1; y: string; } +>x : 1 +>1 : 1 +>y : string +>'foo' : "foo" + diff --git a/tests/cases/compiler/revertedIntersection.ts b/tests/cases/compiler/revertedIntersection.ts new file mode 100644 index 0000000000000..854c71cdbe7e4 --- /dev/null +++ b/tests/cases/compiler/revertedIntersection.ts @@ -0,0 +1,92 @@ +// @strict: true + +type StateConfig = { + entry?: TAction + states?: Record>; +}; + +type StateSchema = { + states?: Record; +}; + +declare function createMachine< + TConfig extends StateConfig, + TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, +>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; + +const inferredParams1 = createMachine({ + entry: "foo", + states: { + a: { + entry: "bar", + }, + }, + extra: 12, +}); + +const inferredParams2 = createMachine({ + entry: "foo", + states: { + a: { + entry: "foo", + }, + }, + extra: 12, +}); + + +// ----------------------------------------------------------------------------------------- + +const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; + +const checked = checkType<{x: number, y: string}>()({ + x: 1 as number, + y: "y", + z: "z", // undesirable property z is *not* allowed +}); + +checked; + // ^? + +// ----------------------------------------------------------------------------------------- + +interface Stuff { + field: number; + anotherField: string; +} + +function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { + if(Math.random() > 0.5) { + return s as T + } else { + return s + } +} + +doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) + +function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { + if(Math.random() > 0.5) { + return arr as T[] + } else { + return arr + } +} + +doStuffWithStuffArr([ + { field: 1, anotherField: 'a', extra: 123 }, +]) + +// ----------------------------------------------------------------------------------------- + +type XNumber = { x: number } + +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; + +function bar(props: {x: number, y: string}) { + return foo(props); // no error because lack of excess property check by design +} + +foo({x: 1, y: 'foo'}); + +foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design \ No newline at end of file From 83964d3cd883aaa558fd5080e12604562d7bbbd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Mon, 18 Sep 2023 19:28:48 +0200 Subject: [PATCH 2/8] Reverse limiting constraint --- src/compiler/checker.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cdba5f2a0e5e5..df94ee4831761 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13484,6 +13484,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return instantiateType(instantiable, createTypeMapper([type.indexType, type.objectType], [getNumberLiteralType(0), createTupleType([replacement])])); } + function getLimitedConstraint(type: ReverseMappedType) { + const constraint = getConstraintTypeFromMappedType(type.mappedType); + if (!(constraint.flags & TypeFlags.Union)) { + return; + } + const origin = (constraint as UnionType).origin; + if (!origin || !(origin.flags & TypeFlags.Intersection)) { + return; + } + const limitedConstraint = getIntersectionType((origin as IntersectionType).types.filter(t => t !== type.constraintType)); + return limitedConstraint !== neverType ? limitedConstraint : undefined; + } + function resolveReverseMappedTypeMembers(type: ReverseMappedType) { const indexInfo = getIndexInfoOfType(type.source, stringType); const modifiers = getMappedTypeModifiers(type.mappedType); @@ -13491,7 +13504,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const optionalMask = modifiers & MappedTypeModifiers.IncludeOptional ? 0 : SymbolFlags.Optional; const indexInfos = indexInfo ? [createIndexInfo(stringType, inferReverseMappedType(indexInfo.type, type.mappedType, type.constraintType), readonlyMask && indexInfo.isReadonly)] : emptyArray; const members = createSymbolTable(); + const limitedConstraint = getLimitedConstraint(type); for (const prop of getPropertiesOfType(type.source)) { + if (limitedConstraint) { + const propertyNameType = getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique); + if (!isTypeAssignableTo(propertyNameType, limitedConstraint)) { + continue; + } + } const checkFlags = CheckFlags.ReverseMapped | (readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0); const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags) as ReverseMappedSymbol; inferredProp.declarations = prop.declarations; From 1df36619cc144cbaaee4c2e41b52a25f82d05231 Mon Sep 17 00:00:00 2001 From: Andrea Simone Costa Date: Thu, 21 Sep 2023 10:44:11 +0200 Subject: [PATCH 3/8] enhance getLimitedConstraint, add test case --- src/compiler/checker.ts | 4 +- .../reverseLimitedConstraint.errors.txt | 24 ++++++++ .../reference/reverseLimitedConstraint.js | 28 ++++++++++ .../reverseLimitedConstraint.symbols | 55 +++++++++++++++++++ .../reference/reverseLimitedConstraint.types | 52 ++++++++++++++++++ .../compiler/reverseLimitedConstraint.ts | 15 +++++ 6 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/reverseLimitedConstraint.errors.txt create mode 100644 tests/baselines/reference/reverseLimitedConstraint.js create mode 100644 tests/baselines/reference/reverseLimitedConstraint.symbols create mode 100644 tests/baselines/reference/reverseLimitedConstraint.types create mode 100644 tests/cases/compiler/reverseLimitedConstraint.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index df94ee4831761..f5348f0ed6333 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13486,10 +13486,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function getLimitedConstraint(type: ReverseMappedType) { const constraint = getConstraintTypeFromMappedType(type.mappedType); - if (!(constraint.flags & TypeFlags.Union)) { + if (!(constraint.flags & TypeFlags.Union || constraint.flags & TypeFlags.Intersection)) { return; } - const origin = (constraint as UnionType).origin; + const origin = (constraint.flags & TypeFlags.Union) ? (constraint as UnionType).origin : (constraint as IntersectionType); if (!origin || !(origin.flags & TypeFlags.Intersection)) { return; } diff --git a/tests/baselines/reference/reverseLimitedConstraint.errors.txt b/tests/baselines/reference/reverseLimitedConstraint.errors.txt new file mode 100644 index 0000000000000..724078c43749d --- /dev/null +++ b/tests/baselines/reference/reverseLimitedConstraint.errors.txt @@ -0,0 +1,24 @@ +reverseLimitedConstraint.ts(5,13): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. +reverseLimitedConstraint.ts(14,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. + + +==== reverseLimitedConstraint.ts (2 errors) ==== + type XNumber_ = { x: number } + + declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; + + foo_({x: 1, y: 'foo'}); + ~ +!!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. + + // ----------------------------------------------------------------------------------------- + + const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; + + const checked_ = checkType_<{x: number, y: string}>()({ + x: 1 as number, + y: "y", + z: "z", + ~ +!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. + }); \ No newline at end of file diff --git a/tests/baselines/reference/reverseLimitedConstraint.js b/tests/baselines/reference/reverseLimitedConstraint.js new file mode 100644 index 0000000000000..dc6e90156e5b7 --- /dev/null +++ b/tests/baselines/reference/reverseLimitedConstraint.js @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/reverseLimitedConstraint.ts] //// + +//// [reverseLimitedConstraint.ts] +type XNumber_ = { x: number } + +declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; + +foo_({x: 1, y: 'foo'}); + +// ----------------------------------------------------------------------------------------- + +const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; + +const checked_ = checkType_<{x: number, y: string}>()({ + x: 1 as number, + y: "y", + z: "z", +}); + +//// [reverseLimitedConstraint.js] +foo_({ x: 1, y: 'foo' }); +// ----------------------------------------------------------------------------------------- +var checkType_ = function () { return function (value) { return value; }; }; +var checked_ = checkType_()({ + x: 1, + y: "y", + z: "z", +}); diff --git a/tests/baselines/reference/reverseLimitedConstraint.symbols b/tests/baselines/reference/reverseLimitedConstraint.symbols new file mode 100644 index 0000000000000..70e76eb8b5a21 --- /dev/null +++ b/tests/baselines/reference/reverseLimitedConstraint.symbols @@ -0,0 +1,55 @@ +//// [tests/cases/compiler/reverseLimitedConstraint.ts] //// + +=== reverseLimitedConstraint.ts === +type XNumber_ = { x: number } +>XNumber_ : Symbol(XNumber_, Decl(reverseLimitedConstraint.ts, 0, 0)) +>x : Symbol(x, Decl(reverseLimitedConstraint.ts, 0, 17)) + +declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; +>foo_ : Symbol(foo_, Decl(reverseLimitedConstraint.ts, 0, 29)) +>T : Symbol(T, Decl(reverseLimitedConstraint.ts, 2, 22)) +>XNumber_ : Symbol(XNumber_, Decl(reverseLimitedConstraint.ts, 0, 0)) +>props : Symbol(props, Decl(reverseLimitedConstraint.ts, 2, 42)) +>K : Symbol(K, Decl(reverseLimitedConstraint.ts, 2, 51)) +>T : Symbol(T, Decl(reverseLimitedConstraint.ts, 2, 22)) +>XNumber_ : Symbol(XNumber_, Decl(reverseLimitedConstraint.ts, 0, 0)) +>T : Symbol(T, Decl(reverseLimitedConstraint.ts, 2, 22)) +>K : Symbol(K, Decl(reverseLimitedConstraint.ts, 2, 51)) +>T : Symbol(T, Decl(reverseLimitedConstraint.ts, 2, 22)) + +foo_({x: 1, y: 'foo'}); +>foo_ : Symbol(foo_, Decl(reverseLimitedConstraint.ts, 0, 29)) +>x : Symbol(x, Decl(reverseLimitedConstraint.ts, 4, 6)) +>y : Symbol(y, Decl(reverseLimitedConstraint.ts, 4, 11)) + +// ----------------------------------------------------------------------------------------- + +const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; +>checkType_ : Symbol(checkType_, Decl(reverseLimitedConstraint.ts, 8, 5)) +>T : Symbol(T, Decl(reverseLimitedConstraint.ts, 8, 20)) +>U : Symbol(U, Decl(reverseLimitedConstraint.ts, 8, 29)) +>T : Symbol(T, Decl(reverseLimitedConstraint.ts, 8, 20)) +>value : Symbol(value, Decl(reverseLimitedConstraint.ts, 8, 42)) +>K : Symbol(K, Decl(reverseLimitedConstraint.ts, 8, 52)) +>U : Symbol(U, Decl(reverseLimitedConstraint.ts, 8, 29)) +>T : Symbol(T, Decl(reverseLimitedConstraint.ts, 8, 20)) +>U : Symbol(U, Decl(reverseLimitedConstraint.ts, 8, 29)) +>K : Symbol(K, Decl(reverseLimitedConstraint.ts, 8, 52)) +>value : Symbol(value, Decl(reverseLimitedConstraint.ts, 8, 42)) + +const checked_ = checkType_<{x: number, y: string}>()({ +>checked_ : Symbol(checked_, Decl(reverseLimitedConstraint.ts, 10, 5)) +>checkType_ : Symbol(checkType_, Decl(reverseLimitedConstraint.ts, 8, 5)) +>x : Symbol(x, Decl(reverseLimitedConstraint.ts, 10, 29)) +>y : Symbol(y, Decl(reverseLimitedConstraint.ts, 10, 39)) + + x: 1 as number, +>x : Symbol(x, Decl(reverseLimitedConstraint.ts, 10, 55)) + + y: "y", +>y : Symbol(y, Decl(reverseLimitedConstraint.ts, 11, 17)) + + z: "z", +>z : Symbol(z, Decl(reverseLimitedConstraint.ts, 12, 9)) + +}); diff --git a/tests/baselines/reference/reverseLimitedConstraint.types b/tests/baselines/reference/reverseLimitedConstraint.types new file mode 100644 index 0000000000000..1546fc8184fd9 --- /dev/null +++ b/tests/baselines/reference/reverseLimitedConstraint.types @@ -0,0 +1,52 @@ +//// [tests/cases/compiler/reverseLimitedConstraint.ts] //// + +=== reverseLimitedConstraint.ts === +type XNumber_ = { x: number } +>XNumber_ : { x: number; } +>x : number + +declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; +>foo_ : (props: { [K in keyof T & "x"]: T[K]; }) => T +>props : { [K in keyof T & "x"]: T[K]; } + +foo_({x: 1, y: 'foo'}); +>foo_({x: 1, y: 'foo'}) : { x: 1; } +>foo_ : (props: { [K in keyof T & "x"]: T[K]; }) => T +>{x: 1, y: 'foo'} : { x: 1; y: string; } +>x : 1 +>1 : 1 +>y : string +>'foo' : "foo" + +// ----------------------------------------------------------------------------------------- + +const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; +>checkType_ : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>() => (value: { [K in keyof U & keyof T]: U[K] }) => value : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>(value: { [K in keyof U & keyof T]: U[K] }) => value : (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>value : { [K in keyof U & keyof T]: U[K]; } +>value : { [K in keyof U & keyof T]: U[K]; } + +const checked_ = checkType_<{x: number, y: string}>()({ +>checked_ : { x: number; y: "y"; } +>checkType_<{x: number, y: string}>()({ x: 1 as number, y: "y", z: "z",}) : { x: number; y: "y"; } +>checkType_<{x: number, y: string}>() : (value: { [K in keyof U & ("x" | "y")]: U[K]; }) => { [K in keyof U & ("x" | "y")]: U[K]; } +>checkType_ : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>x : number +>y : string +>{ x: 1 as number, y: "y", z: "z",} : { x: number; y: "y"; z: string; } + + x: 1 as number, +>x : number +>1 as number : number +>1 : 1 + + y: "y", +>y : "y" +>"y" : "y" + + z: "z", +>z : string +>"z" : "z" + +}); diff --git a/tests/cases/compiler/reverseLimitedConstraint.ts b/tests/cases/compiler/reverseLimitedConstraint.ts new file mode 100644 index 0000000000000..7618ae65046a9 --- /dev/null +++ b/tests/cases/compiler/reverseLimitedConstraint.ts @@ -0,0 +1,15 @@ +type XNumber_ = { x: number } + +declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; + +foo_({x: 1, y: 'foo'}); + +// ----------------------------------------------------------------------------------------- + +const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; + +const checked_ = checkType_<{x: number, y: string}>()({ + x: 1 as number, + y: "y", + z: "z", +}); \ No newline at end of file From 702c0026c2a5a7345163b5f11f587830c9c57b64 Mon Sep 17 00:00:00 2001 From: Andrea Simone Costa Date: Thu, 21 Sep 2023 10:47:10 +0200 Subject: [PATCH 4/8] enhance tests --- .../reverseLimitedConstraint.symbols | 55 -- ...appedTypeIntersectionConstraint.errors.txt | 239 ++++++++ ...everseMappedTypeIntersectionConstraint.js} | 127 ++++- ...seMappedTypeIntersectionConstraint.symbols | 520 ++++++++++++++++++ ...rseMappedTypeIntersectionConstraint.types} | 237 +++++++- ...rseMappedTypeLimitedConstraint.errors.txt} | 6 +- ... => reverseMappedTypeLimitedConstraint.js} | 6 +- ...reverseMappedTypeLimitedConstraint.symbols | 55 ++ ... reverseMappedTypeLimitedConstraint.types} | 4 +- .../reference/revertedIntersection.errors.txt | 124 ----- .../reference/revertedIntersection.symbols | 257 --------- ...reverseMappedTypeIntersectionConstraint.ts | 180 ++++++ ... => reverseMappedTypeLimitedConstraint.ts} | 0 tests/cases/compiler/revertedIntersection.ts | 92 ---- 14 files changed, 1360 insertions(+), 542 deletions(-) delete mode 100644 tests/baselines/reference/reverseLimitedConstraint.symbols create mode 100644 tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt rename tests/baselines/reference/{revertedIntersection.js => reverseMappedTypeIntersectionConstraint.js} (56%) create mode 100644 tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols rename tests/baselines/reference/{revertedIntersection.types => reverseMappedTypeIntersectionConstraint.types} (51%) rename tests/baselines/reference/{reverseLimitedConstraint.errors.txt => reverseMappedTypeLimitedConstraint.errors.txt} (65%) rename tests/baselines/reference/{reverseLimitedConstraint.js => reverseMappedTypeLimitedConstraint.js} (80%) create mode 100644 tests/baselines/reference/reverseMappedTypeLimitedConstraint.symbols rename tests/baselines/reference/{reverseLimitedConstraint.types => reverseMappedTypeLimitedConstraint.types} (92%) delete mode 100644 tests/baselines/reference/revertedIntersection.errors.txt delete mode 100644 tests/baselines/reference/revertedIntersection.symbols create mode 100644 tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts rename tests/cases/compiler/{reverseLimitedConstraint.ts => reverseMappedTypeLimitedConstraint.ts} (100%) delete mode 100644 tests/cases/compiler/revertedIntersection.ts diff --git a/tests/baselines/reference/reverseLimitedConstraint.symbols b/tests/baselines/reference/reverseLimitedConstraint.symbols deleted file mode 100644 index 70e76eb8b5a21..0000000000000 --- a/tests/baselines/reference/reverseLimitedConstraint.symbols +++ /dev/null @@ -1,55 +0,0 @@ -//// [tests/cases/compiler/reverseLimitedConstraint.ts] //// - -=== reverseLimitedConstraint.ts === -type XNumber_ = { x: number } ->XNumber_ : Symbol(XNumber_, Decl(reverseLimitedConstraint.ts, 0, 0)) ->x : Symbol(x, Decl(reverseLimitedConstraint.ts, 0, 17)) - -declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; ->foo_ : Symbol(foo_, Decl(reverseLimitedConstraint.ts, 0, 29)) ->T : Symbol(T, Decl(reverseLimitedConstraint.ts, 2, 22)) ->XNumber_ : Symbol(XNumber_, Decl(reverseLimitedConstraint.ts, 0, 0)) ->props : Symbol(props, Decl(reverseLimitedConstraint.ts, 2, 42)) ->K : Symbol(K, Decl(reverseLimitedConstraint.ts, 2, 51)) ->T : Symbol(T, Decl(reverseLimitedConstraint.ts, 2, 22)) ->XNumber_ : Symbol(XNumber_, Decl(reverseLimitedConstraint.ts, 0, 0)) ->T : Symbol(T, Decl(reverseLimitedConstraint.ts, 2, 22)) ->K : Symbol(K, Decl(reverseLimitedConstraint.ts, 2, 51)) ->T : Symbol(T, Decl(reverseLimitedConstraint.ts, 2, 22)) - -foo_({x: 1, y: 'foo'}); ->foo_ : Symbol(foo_, Decl(reverseLimitedConstraint.ts, 0, 29)) ->x : Symbol(x, Decl(reverseLimitedConstraint.ts, 4, 6)) ->y : Symbol(y, Decl(reverseLimitedConstraint.ts, 4, 11)) - -// ----------------------------------------------------------------------------------------- - -const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; ->checkType_ : Symbol(checkType_, Decl(reverseLimitedConstraint.ts, 8, 5)) ->T : Symbol(T, Decl(reverseLimitedConstraint.ts, 8, 20)) ->U : Symbol(U, Decl(reverseLimitedConstraint.ts, 8, 29)) ->T : Symbol(T, Decl(reverseLimitedConstraint.ts, 8, 20)) ->value : Symbol(value, Decl(reverseLimitedConstraint.ts, 8, 42)) ->K : Symbol(K, Decl(reverseLimitedConstraint.ts, 8, 52)) ->U : Symbol(U, Decl(reverseLimitedConstraint.ts, 8, 29)) ->T : Symbol(T, Decl(reverseLimitedConstraint.ts, 8, 20)) ->U : Symbol(U, Decl(reverseLimitedConstraint.ts, 8, 29)) ->K : Symbol(K, Decl(reverseLimitedConstraint.ts, 8, 52)) ->value : Symbol(value, Decl(reverseLimitedConstraint.ts, 8, 42)) - -const checked_ = checkType_<{x: number, y: string}>()({ ->checked_ : Symbol(checked_, Decl(reverseLimitedConstraint.ts, 10, 5)) ->checkType_ : Symbol(checkType_, Decl(reverseLimitedConstraint.ts, 8, 5)) ->x : Symbol(x, Decl(reverseLimitedConstraint.ts, 10, 29)) ->y : Symbol(y, Decl(reverseLimitedConstraint.ts, 10, 39)) - - x: 1 as number, ->x : Symbol(x, Decl(reverseLimitedConstraint.ts, 10, 55)) - - y: "y", ->y : Symbol(y, Decl(reverseLimitedConstraint.ts, 11, 17)) - - z: "z", ->z : Symbol(z, Decl(reverseLimitedConstraint.ts, 12, 9)) - -}); diff --git a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt new file mode 100644 index 0000000000000..9b11707303d0a --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt @@ -0,0 +1,239 @@ +reverseMappedTypeIntersectionConstraint.ts(19,7): error TS2322: Type '"bar"' is not assignable to type '"foo"'. +reverseMappedTypeIntersectionConstraint.ts(32,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ entry: "foo"; states: { a: { entry: "foo"; }; }; }'. +reverseMappedTypeIntersectionConstraint.ts(43,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. +reverseMappedTypeIntersectionConstraint.ts(60,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. + '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. +reverseMappedTypeIntersectionConstraint.ts(64,49): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. +reverseMappedTypeIntersectionConstraint.ts(70,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. + Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. + '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. +reverseMappedTypeIntersectionConstraint.ts(75,36): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. +reverseMappedTypeIntersectionConstraint.ts(88,12): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. +reverseMappedTypeIntersectionConstraint.ts(99,12): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; }'. +reverseMappedTypeIntersectionConstraint.ts(101,22): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; y: "foo"; }'. +reverseMappedTypeIntersectionConstraint.ts(114,67): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ prop: "foo"; nested: { prop: string; }; }'. +reverseMappedTypeIntersectionConstraint.ts(160,21): error TS2585: 'Promise' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. +reverseMappedTypeIntersectionConstraint.ts(173,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors?: { src: "str"; logic: () => any; } | undefined; } | undefined; invoke: { src: "str"; }; }'. +reverseMappedTypeIntersectionConstraint.ts(182,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ invoke: { src: "whatever"; }; }'. + + +==== reverseMappedTypeIntersectionConstraint.ts (14 errors) ==== + type StateConfig = { + entry?: TAction + states?: Record>; + }; + + type StateSchema = { + states?: Record; + }; + + declare function createMachine< + TConfig extends StateConfig, + TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, + >(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; + + const inferredParams1 = createMachine({ + entry: "foo", + states: { + a: { + entry: "bar", + ~~~~~ +!!! error TS2322: Type '"bar"' is not assignable to type '"foo"'. +!!! related TS6500 reverseMappedTypeIntersectionConstraint.ts:2:3: The expected type comes from property 'entry' which is declared here on type 'StateConfig<"foo">' + }, + }, + extra: 12, + }); + + const inferredParams2 = createMachine({ + entry: "foo", + states: { + a: { + entry: "foo", + }, + }, + extra: 12, + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ entry: "foo"; states: { a: { entry: "foo"; }; }; }'. + }); + + + // ----------------------------------------------------------------------------------------- + + const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; + + const checked = checkType<{x: number, y: string}>()({ + x: 1 as number, + y: "y", + z: "z", // undesirable property z is *not* allowed + ~ +!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. + }); + + checked; + // ^? + + // ----------------------------------------------------------------------------------------- + + interface Stuff { + field: number; + anotherField: string; + } + + function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { + if(Math.random() > 0.5) { + return s as T + } else { + return s + ~~~~~~ +!!! error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. +!!! error TS2322: '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. + } + } + + doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. + + function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { + if(Math.random() > 0.5) { + return arr as T[] + } else { + return arr + ~~~~~~ +!!! error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. +!!! error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. +!!! error TS2322: '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. + } + } + + doStuffWithStuffArr([ + { field: 1, anotherField: 'a', extra: 123 }, + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. + ]) + + // ----------------------------------------------------------------------------------------- + + type XNumber = { x: number } + + declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; + + function bar(props: {x: number, y: string}) { + return foo(props); // no error because lack of excess property check by design + } + + foo({x: 1, y: 'foo'}); + ~ +!!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. + + foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design + + // ----------------------------------------------------------------------------------------- + + type NoErrWithOptProps = { x: number, y?: string } + + declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; + + baz({x: 1}); + baz({x: 1, z: 123}); + ~ +!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; }'. + baz({x: 1, y: 'foo'}); + baz({x: 1, y: 'foo', z: 123}); + ~ +!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; y: "foo"; }'. + + // ----------------------------------------------------------------------------------------- + + interface WithNestedProp { + prop: string; + nested: { + prop: string; + } + } + + declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; + + const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ prop: "foo"; nested: { prop: string; }; }'. + // ^? + + // ----------------------------------------------------------------------------------------- + + type IsLiteralString = string extends T ? false : true; + + type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } + + interface ProvidedActor { + src: string; + logic: () => Promise; + } + + interface InferenceSource { + types?: { + actors?: TActor; + }; + } + + type DistributeActors = TActor extends { src: infer TSrc } + ? { + src: TSrc; + } + : never; + + interface MachineConfig { + types?: { + actors?: TActor; + }; + invoke: IsLiteralString extends true + ? DistributeActors + : { + src: string; + }; + } + + type NoExtra = { + [K in keyof T]: K extends keyof MachineConfig ? T[K] : never + } + + declare function createMachine2< + TConfig extends MachineConfig, + TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, + >(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; + + const child = () => Promise.resolve("foo"); + ~~~~~~~ +!!! error TS2585: 'Promise' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. + + const config = createMachine2({ + // ^? + types: {} as { + actors: { + src: "str"; + logic: typeof child; + }; + }, + invoke: { + src: "str", + }, + extra: 10 + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors?: { src: "str"; logic: () => any; } | undefined; } | undefined; invoke: { src: "str"; }; }'. + }); + + + + const config2 = createMachine2({ + invoke: { + src: "whatever" as const, + }, + extra: 10 + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ invoke: { src: "whatever"; }; }'. + }); + + config2 + // ^? + \ No newline at end of file diff --git a/tests/baselines/reference/revertedIntersection.js b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js similarity index 56% rename from tests/baselines/reference/revertedIntersection.js rename to tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js index 4eb7df60cbdd7..551fd92c14ead 100644 --- a/tests/baselines/reference/revertedIntersection.js +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js @@ -1,6 +1,6 @@ -//// [tests/cases/compiler/revertedIntersection.ts] //// +//// [tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts] //// -//// [revertedIntersection.ts] +//// [reverseMappedTypeIntersectionConstraint.ts] type StateConfig = { entry?: TAction states?: Record>; @@ -90,9 +90,106 @@ function bar(props: {x: number, y: string}) { foo({x: 1, y: 'foo'}); -foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design +foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design + +// ----------------------------------------------------------------------------------------- + +type NoErrWithOptProps = { x: number, y?: string } + +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; + +baz({x: 1}); +baz({x: 1, z: 123}); +baz({x: 1, y: 'foo'}); +baz({x: 1, y: 'foo', z: 123}); + +// ----------------------------------------------------------------------------------------- + +interface WithNestedProp { + prop: string; + nested: { + prop: string; + } +} + +declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; + +const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); +// ^? + +// ----------------------------------------------------------------------------------------- + +type IsLiteralString = string extends T ? false : true; + +type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } + +interface ProvidedActor { + src: string; + logic: () => Promise; +} + +interface InferenceSource { + types?: { + actors?: TActor; + }; +} + +type DistributeActors = TActor extends { src: infer TSrc } + ? { + src: TSrc; + } + : never; + +interface MachineConfig { + types?: { + actors?: TActor; + }; + invoke: IsLiteralString extends true + ? DistributeActors + : { + src: string; + }; +} + +type NoExtra = { + [K in keyof T]: K extends keyof MachineConfig ? T[K] : never +} + +declare function createMachine2< + TConfig extends MachineConfig, + TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, +>(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; + +const child = () => Promise.resolve("foo"); + +const config = createMachine2({ + // ^? + types: {} as { + actors: { + src: "str"; + logic: typeof child; + }; + }, + invoke: { + src: "str", + }, + extra: 10 +}); + + + +const config2 = createMachine2({ + invoke: { + src: "whatever" as const, + }, + extra: 10 +}); + +config2 +// ^? -//// [revertedIntersection.js] + +//// [reverseMappedTypeIntersectionConstraint.js] "use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { @@ -156,3 +253,25 @@ function bar(props) { } foo({ x: 1, y: 'foo' }); foo(__assign({ x: 1, y: 'foo' })); // no error because lack of excess property check by design +baz({ x: 1 }); +baz({ x: 1, z: 123 }); +baz({ x: 1, y: 'foo' }); +baz({ x: 1, y: 'foo', z: 123 }); +var wnp = withNestedProp({ prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); +var child = function () { return Promise.resolve("foo"); }; +var config = createMachine2({ + // ^? + types: {}, + invoke: { + src: "str", + }, + extra: 10 +}); +var config2 = createMachine2({ + invoke: { + src: "whatever", + }, + extra: 10 +}); +config2; +// ^? diff --git a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols new file mode 100644 index 0000000000000..8b07ca8c6ebd3 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols @@ -0,0 +1,520 @@ +//// [tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts] //// + +=== reverseMappedTypeIntersectionConstraint.ts === +type StateConfig = { +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 17)) + + entry?: TAction +>entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 44)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 17)) + + states?: Record>; +>states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 1, 17)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 17)) + +}; + +type StateSchema = { +>StateSchema : Symbol(StateSchema, Decl(reverseMappedTypeIntersectionConstraint.ts, 3, 2)) + + states?: Record; +>states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 5, 20)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>StateSchema : Symbol(StateSchema, Decl(reverseMappedTypeIntersectionConstraint.ts, 3, 2)) + +}; + +declare function createMachine< +>createMachine : Symbol(createMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 7, 2)) + + TConfig extends StateConfig, +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 10, 39)) + + TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 10, 39)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) + +>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; +>config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 12, 2)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 12, 13)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 10, 39)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 12, 13)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 10, 39)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) + +const inferredParams1 = createMachine({ +>inferredParams1 : Symbol(inferredParams1, Decl(reverseMappedTypeIntersectionConstraint.ts, 14, 5)) +>createMachine : Symbol(createMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 7, 2)) + + entry: "foo", +>entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 14, 39)) + + states: { +>states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 15, 15)) + + a: { +>a : Symbol(a, Decl(reverseMappedTypeIntersectionConstraint.ts, 16, 11)) + + entry: "bar", +>entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 17, 8)) + + }, + }, + extra: 12, +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 20, 4)) + +}); + +const inferredParams2 = createMachine({ +>inferredParams2 : Symbol(inferredParams2, Decl(reverseMappedTypeIntersectionConstraint.ts, 24, 5)) +>createMachine : Symbol(createMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 7, 2)) + + entry: "foo", +>entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 24, 39)) + + states: { +>states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 25, 15)) + + a: { +>a : Symbol(a, Decl(reverseMappedTypeIntersectionConstraint.ts, 26, 11)) + + entry: "foo", +>entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 27, 8)) + + }, + }, + extra: 12, +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 30, 4)) + +}); + + +// ----------------------------------------------------------------------------------------- + +const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; +>checkType : Symbol(checkType, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 5)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 19)) +>U : Symbol(U, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 28)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 19)) +>value : Symbol(value, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 41)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 51)) +>U : Symbol(U, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 28)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 19)) +>U : Symbol(U, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 28)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 51)) +>value : Symbol(value, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 41)) + +const checked = checkType<{x: number, y: string}>()({ +>checked : Symbol(checked, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 5)) +>checkType : Symbol(checkType, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 5)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 27)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 37)) + + x: 1 as number, +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 53)) + + y: "y", +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 40, 17)) + + z: "z", // undesirable property z is *not* allowed +>z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 41, 9)) + +}); + +checked; +>checked : Symbol(checked, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 5)) + + // ^? + +// ----------------------------------------------------------------------------------------- + +interface Stuff { +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) + + field: number; +>field : Symbol(Stuff.field, Decl(reverseMappedTypeIntersectionConstraint.ts, 50, 17)) + + anotherField: string; +>anotherField : Symbol(Stuff.anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 51, 18)) +} + +function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { +>doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 53, 1)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 26)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) +>s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 43)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 49)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 26)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 26)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 49)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 26)) + + if(Math.random() > 0.5) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + return s as T +>s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 43)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 26)) + + } else { + return s +>s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 43)) + } +} + +doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) +>doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 53, 1)) +>field : Symbol(field, Decl(reverseMappedTypeIntersectionConstraint.ts, 63, 18)) +>anotherField : Symbol(anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 63, 28)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 63, 47)) + +function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { +>doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeIntersectionConstraint.ts, 63, 61)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 29)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) +>arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 46)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 54)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 29)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 29)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 54)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 29)) + + if(Math.random() > 0.5) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + return arr as T[] +>arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 46)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 29)) + + } else { + return arr +>arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 46)) + } +} + +doStuffWithStuffArr([ +>doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeIntersectionConstraint.ts, 63, 61)) + + { field: 1, anotherField: 'a', extra: 123 }, +>field : Symbol(field, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 5)) +>anotherField : Symbol(anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 15)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 34)) + +]) + +// ----------------------------------------------------------------------------------------- + +type XNumber = { x: number } +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 75, 2)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 79, 16)) + +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 79, 28)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 81, 21)) +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 75, 2)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 81, 40)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 81, 49)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 81, 21)) +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 75, 2)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 81, 21)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 81, 49)) + +function bar(props: {x: number, y: string}) { +>bar : Symbol(bar, Decl(reverseMappedTypeIntersectionConstraint.ts, 81, 93)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 83, 13)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 83, 21)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 83, 31)) + + return foo(props); // no error because lack of excess property check by design +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 79, 28)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 83, 13)) +} + +foo({x: 1, y: 'foo'}); +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 79, 28)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 87, 5)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 87, 10)) + +foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 79, 28)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 89, 9)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 89, 14)) + +// ----------------------------------------------------------------------------------------- + +type NoErrWithOptProps = { x: number, y?: string } +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 89, 27)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 26)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 37)) + +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 50)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 95, 21)) +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 89, 27)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 95, 50)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 95, 59)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 95, 21)) +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 89, 27)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 95, 21)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 95, 59)) + +baz({x: 1}); +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 97, 5)) + +baz({x: 1, z: 123}); +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 98, 5)) +>z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 98, 10)) + +baz({x: 1, y: 'foo'}); +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 5)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 10)) + +baz({x: 1, y: 'foo', z: 123}); +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 100, 5)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 100, 10)) +>z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 100, 20)) + +// ----------------------------------------------------------------------------------------- + +interface WithNestedProp { +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 100, 30)) + + prop: string; +>prop : Symbol(WithNestedProp.prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 26)) + + nested: { +>nested : Symbol(WithNestedProp.nested, Decl(reverseMappedTypeIntersectionConstraint.ts, 105, 15)) + + prop: string; +>prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 106, 11)) + } +} + +declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; +>withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 109, 1)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 111, 32)) +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 100, 30)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 111, 58)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 111, 67)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 111, 32)) +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 100, 30)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 111, 32)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 111, 67)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 111, 32)) + +const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); +>wnp : Symbol(wnp, Decl(reverseMappedTypeIntersectionConstraint.ts, 113, 5)) +>withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 109, 1)) +>prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 113, 28)) +>nested : Symbol(nested, Decl(reverseMappedTypeIntersectionConstraint.ts, 113, 40)) +>prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 113, 50)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 113, 65)) + +// ^? + +// ----------------------------------------------------------------------------------------- + +type IsLiteralString = string extends T ? false : true; +>IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeIntersectionConstraint.ts, 113, 79)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 21)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 21)) + +type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } +>DeepWritable : Symbol(DeepWritable, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 73)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 18)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 18)) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 18)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 61)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 18)) +>DeepWritable : Symbol(DeepWritable, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 73)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 18)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 61)) + +interface ProvidedActor { +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 96)) + + src: string; +>src : Symbol(ProvidedActor.src, Decl(reverseMappedTypeIntersectionConstraint.ts, 122, 25)) + + logic: () => Promise; +>logic : Symbol(ProvidedActor.logic, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 14)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) +} + +interface InferenceSource { +>InferenceSource : Symbol(InferenceSource, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 1)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 127, 26)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 96)) + + types?: { +>types : Symbol(InferenceSource.types, Decl(reverseMappedTypeIntersectionConstraint.ts, 127, 57)) + + actors?: TActor; +>actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 128, 11)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 127, 26)) + + }; +} + +type DistributeActors = TActor extends { src: infer TSrc } +>DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 1)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 133, 22)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 133, 22)) +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 133, 48)) +>TSrc : Symbol(TSrc, Decl(reverseMappedTypeIntersectionConstraint.ts, 133, 59)) + + ? { + src: TSrc; +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 134, 5)) +>TSrc : Symbol(TSrc, Decl(reverseMappedTypeIntersectionConstraint.ts, 133, 59)) + } + : never; + +interface MachineConfig { +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 137, 10)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 139, 24)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 96)) + + types?: { +>types : Symbol(MachineConfig.types, Decl(reverseMappedTypeIntersectionConstraint.ts, 139, 55)) + + actors?: TActor; +>actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 140, 11)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 139, 24)) + + }; + invoke: IsLiteralString extends true +>invoke : Symbol(MachineConfig.invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 142, 4)) +>IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeIntersectionConstraint.ts, 113, 79)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 139, 24)) + + ? DistributeActors +>DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 1)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 139, 24)) + + : { + src: string; +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 145, 7)) + + }; +} + +type NoExtra = { +>NoExtra : Symbol(NoExtra, Decl(reverseMappedTypeIntersectionConstraint.ts, 148, 1)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 150, 13)) + + [K in keyof T]: K extends keyof MachineConfig ? T[K] : never +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 151, 3)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 150, 13)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 151, 3)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 137, 10)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 150, 13)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 151, 3)) +} + +declare function createMachine2< +>createMachine2 : Symbol(createMachine2, Decl(reverseMappedTypeIntersectionConstraint.ts, 152, 1)) + + TConfig extends MachineConfig, +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 32)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 137, 10)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 155, 40)) + + TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 155, 40)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 96)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 32)) +>types : Symbol(types, Decl(reverseMappedTypeIntersectionConstraint.ts, 156, 50)) +>actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 156, 59)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 96)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 32)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 96)) + +>(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; +>config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 157, 2)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 157, 12)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 137, 10)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 32)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 32)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 157, 12)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 32)) + +const child = () => Promise.resolve("foo"); +>child : Symbol(child, Decl(reverseMappedTypeIntersectionConstraint.ts, 159, 5)) + +const config = createMachine2({ +>config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 161, 5)) +>createMachine2 : Symbol(createMachine2, Decl(reverseMappedTypeIntersectionConstraint.ts, 152, 1)) + + // ^? + types: {} as { +>types : Symbol(types, Decl(reverseMappedTypeIntersectionConstraint.ts, 161, 31)) + + actors: { +>actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 163, 16)) + + src: "str"; +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 164, 13)) + + logic: typeof child; +>logic : Symbol(logic, Decl(reverseMappedTypeIntersectionConstraint.ts, 165, 17)) +>child : Symbol(child, Decl(reverseMappedTypeIntersectionConstraint.ts, 159, 5)) + + }; + }, + invoke: { +>invoke : Symbol(invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 168, 4)) + + src: "str", +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 169, 11)) + + }, + extra: 10 +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 171, 4)) + +}); + + + +const config2 = createMachine2({ +>config2 : Symbol(config2, Decl(reverseMappedTypeIntersectionConstraint.ts, 177, 5)) +>createMachine2 : Symbol(createMachine2, Decl(reverseMappedTypeIntersectionConstraint.ts, 152, 1)) + + invoke: { +>invoke : Symbol(invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 177, 32)) + + src: "whatever" as const, +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 178, 11)) +>const : Symbol(const) + + }, + extra: 10 +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 180, 4)) + +}); + +config2 +>config2 : Symbol(config2, Decl(reverseMappedTypeIntersectionConstraint.ts, 177, 5)) + +// ^? + diff --git a/tests/baselines/reference/revertedIntersection.types b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types similarity index 51% rename from tests/baselines/reference/revertedIntersection.types rename to tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types index af5d27503dfe0..d8019a342cf72 100644 --- a/tests/baselines/reference/revertedIntersection.types +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types @@ -1,6 +1,6 @@ -//// [tests/cases/compiler/revertedIntersection.ts] //// +//// [tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts] //// -=== revertedIntersection.ts === +=== reverseMappedTypeIntersectionConstraint.ts === type StateConfig = { >StateConfig : StateConfig @@ -249,3 +249,236 @@ foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by >y : string >'foo' : "foo" +// ----------------------------------------------------------------------------------------- + +type NoErrWithOptProps = { x: number, y?: string } +>NoErrWithOptProps : { x: number; y?: string | undefined; } +>x : number +>y : string | undefined + +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void +>props : { [K in keyof T & keyof NoErrWithOptProps]: T[K]; } + +baz({x: 1}); +>baz({x: 1}) : void +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void +>{x: 1} : { x: 1; } +>x : 1 +>1 : 1 + +baz({x: 1, z: 123}); +>baz({x: 1, z: 123}) : void +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void +>{x: 1, z: 123} : { x: 1; z: number; } +>x : 1 +>1 : 1 +>z : number +>123 : 123 + +baz({x: 1, y: 'foo'}); +>baz({x: 1, y: 'foo'}) : void +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void +>{x: 1, y: 'foo'} : { x: 1; y: "foo"; } +>x : 1 +>1 : 1 +>y : "foo" +>'foo' : "foo" + +baz({x: 1, y: 'foo', z: 123}); +>baz({x: 1, y: 'foo', z: 123}) : void +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void +>{x: 1, y: 'foo', z: 123} : { x: 1; y: "foo"; z: number; } +>x : 1 +>1 : 1 +>y : "foo" +>'foo' : "foo" +>z : number +>123 : 123 + +// ----------------------------------------------------------------------------------------- + +interface WithNestedProp { + prop: string; +>prop : string + + nested: { +>nested : { prop: string; } + + prop: string; +>prop : string + } +} + +declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; +>withNestedProp : (props: { [K in keyof T & keyof WithNestedProp]: T[K]; }) => T +>props : { [K in keyof T & keyof WithNestedProp]: T[K]; } + +const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); +>wnp : { prop: "foo"; nested: { prop: string; }; } +>withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }) : { prop: "foo"; nested: { prop: string; }; } +>withNestedProp : (props: { [K in keyof T & keyof WithNestedProp]: T[K]; }) => T +>{prop: 'foo', nested: { prop: 'bar' }, extra: 10 } : { prop: "foo"; nested: { prop: string; }; extra: number; } +>prop : "foo" +>'foo' : "foo" +>nested : { prop: string; } +>{ prop: 'bar' } : { prop: string; } +>prop : string +>'bar' : "bar" +>extra : number +>10 : 10 + +// ^? + +// ----------------------------------------------------------------------------------------- + +type IsLiteralString = string extends T ? false : true; +>IsLiteralString : IsLiteralString +>false : false +>true : true + +type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } +>DeepWritable : DeepWritable + +interface ProvidedActor { + src: string; +>src : string + + logic: () => Promise; +>logic : () => Promise +} + +interface InferenceSource { + types?: { +>types : { actors?: TActor | undefined; } | undefined + + actors?: TActor; +>actors : TActor | undefined + + }; +} + +type DistributeActors = TActor extends { src: infer TSrc } +>DistributeActors : DistributeActors +>src : TSrc + + ? { + src: TSrc; +>src : TSrc + } + : never; + +interface MachineConfig { + types?: { +>types : { actors?: TActor | undefined; } | undefined + + actors?: TActor; +>actors : TActor | undefined + + }; + invoke: IsLiteralString extends true +>invoke : IsLiteralString extends true ? DistributeActors : { src: string; } +>true : true + + ? DistributeActors + : { + src: string; +>src : string + + }; +} + +type NoExtra = { +>NoExtra : NoExtra + + [K in keyof T]: K extends keyof MachineConfig ? T[K] : never +} + +declare function createMachine2< +>createMachine2 : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor;}; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig + + TConfig extends MachineConfig, + TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, +>types : { actors: ProvidedActor; } +>actors : ProvidedActor + +>(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; +>config : { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; } + +const child = () => Promise.resolve("foo"); +>child : () => any +>() => Promise.resolve("foo") : () => any +>Promise.resolve("foo") : any +>Promise.resolve : any +>Promise : any +>resolve : any +>"foo" : "foo" + +const config = createMachine2({ +>config : MachineConfig<{ src: "str"; logic: typeof child; }> +>createMachine2({ // ^? types: {} as { actors: { src: "str"; logic: typeof child; }; }, invoke: { src: "str", }, extra: 10}) : MachineConfig<{ src: "str"; logic: typeof child; }> +>createMachine2 : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor; }; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig +>{ // ^? types: {} as { actors: { src: "str"; logic: typeof child; }; }, invoke: { src: "str", }, extra: 10} : { types: { actors: { src: "str"; logic: typeof child;}; }; invoke: { src: "str"; }; extra: number; } + + // ^? + types: {} as { +>types : { actors: { src: "str"; logic: typeof child;}; } +>{} as { actors: { src: "str"; logic: typeof child; }; } : { actors: { src: "str"; logic: typeof child;}; } +>{} : {} + + actors: { +>actors : { src: "str"; logic: typeof child; } + + src: "str"; +>src : "str" + + logic: typeof child; +>logic : () => any +>child : () => any + + }; + }, + invoke: { +>invoke : { src: "str"; } +>{ src: "str", } : { src: "str"; } + + src: "str", +>src : "str" +>"str" : "str" + + }, + extra: 10 +>extra : number +>10 : 10 + +}); + + + +const config2 = createMachine2({ +>config2 : { invoke: { src: "whatever"; }; } +>createMachine2({ invoke: { src: "whatever" as const, }, extra: 10}) : { invoke: { src: "whatever"; }; } +>createMachine2 : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor; }; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig +>{ invoke: { src: "whatever" as const, }, extra: 10} : { invoke: { src: "whatever"; }; extra: number; } + + invoke: { +>invoke : { src: "whatever"; } +>{ src: "whatever" as const, } : { src: "whatever"; } + + src: "whatever" as const, +>src : "whatever" +>"whatever" as const : "whatever" +>"whatever" : "whatever" + + }, + extra: 10 +>extra : number +>10 : 10 + +}); + +config2 +>config2 : { invoke: { src: "whatever"; }; } + +// ^? + diff --git a/tests/baselines/reference/reverseLimitedConstraint.errors.txt b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.errors.txt similarity index 65% rename from tests/baselines/reference/reverseLimitedConstraint.errors.txt rename to tests/baselines/reference/reverseMappedTypeLimitedConstraint.errors.txt index 724078c43749d..dc6dc8fa3a331 100644 --- a/tests/baselines/reference/reverseLimitedConstraint.errors.txt +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.errors.txt @@ -1,8 +1,8 @@ -reverseLimitedConstraint.ts(5,13): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. -reverseLimitedConstraint.ts(14,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. +reverseMappedTypeLimitedConstraint.ts(5,13): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. +reverseMappedTypeLimitedConstraint.ts(14,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. -==== reverseLimitedConstraint.ts (2 errors) ==== +==== reverseMappedTypeLimitedConstraint.ts (2 errors) ==== type XNumber_ = { x: number } declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; diff --git a/tests/baselines/reference/reverseLimitedConstraint.js b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.js similarity index 80% rename from tests/baselines/reference/reverseLimitedConstraint.js rename to tests/baselines/reference/reverseMappedTypeLimitedConstraint.js index dc6e90156e5b7..0be7aa8d6a423 100644 --- a/tests/baselines/reference/reverseLimitedConstraint.js +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.js @@ -1,6 +1,6 @@ -//// [tests/cases/compiler/reverseLimitedConstraint.ts] //// +//// [tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts] //// -//// [reverseLimitedConstraint.ts] +//// [reverseMappedTypeLimitedConstraint.ts] type XNumber_ = { x: number } declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; @@ -17,7 +17,7 @@ const checked_ = checkType_<{x: number, y: string}>()({ z: "z", }); -//// [reverseLimitedConstraint.js] +//// [reverseMappedTypeLimitedConstraint.js] foo_({ x: 1, y: 'foo' }); // ----------------------------------------------------------------------------------------- var checkType_ = function () { return function (value) { return value; }; }; diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraint.symbols b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.symbols new file mode 100644 index 0000000000000..5c81507278445 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.symbols @@ -0,0 +1,55 @@ +//// [tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts] //// + +=== reverseMappedTypeLimitedConstraint.ts === +type XNumber_ = { x: number } +>XNumber_ : Symbol(XNumber_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 0)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 17)) + +declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; +>foo_ : Symbol(foo_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 29)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 22)) +>XNumber_ : Symbol(XNumber_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 0)) +>props : Symbol(props, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 42)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 51)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 22)) +>XNumber_ : Symbol(XNumber_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 0)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 22)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 51)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 22)) + +foo_({x: 1, y: 'foo'}); +>foo_ : Symbol(foo_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 29)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraint.ts, 4, 6)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraint.ts, 4, 11)) + +// ----------------------------------------------------------------------------------------- + +const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; +>checkType_ : Symbol(checkType_, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 5)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 20)) +>U : Symbol(U, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 29)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 20)) +>value : Symbol(value, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 42)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 52)) +>U : Symbol(U, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 29)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 20)) +>U : Symbol(U, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 29)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 52)) +>value : Symbol(value, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 42)) + +const checked_ = checkType_<{x: number, y: string}>()({ +>checked_ : Symbol(checked_, Decl(reverseMappedTypeLimitedConstraint.ts, 10, 5)) +>checkType_ : Symbol(checkType_, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 5)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraint.ts, 10, 29)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraint.ts, 10, 39)) + + x: 1 as number, +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraint.ts, 10, 55)) + + y: "y", +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraint.ts, 11, 17)) + + z: "z", +>z : Symbol(z, Decl(reverseMappedTypeLimitedConstraint.ts, 12, 9)) + +}); diff --git a/tests/baselines/reference/reverseLimitedConstraint.types b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.types similarity index 92% rename from tests/baselines/reference/reverseLimitedConstraint.types rename to tests/baselines/reference/reverseMappedTypeLimitedConstraint.types index 1546fc8184fd9..821d7685fcccd 100644 --- a/tests/baselines/reference/reverseLimitedConstraint.types +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.types @@ -1,6 +1,6 @@ -//// [tests/cases/compiler/reverseLimitedConstraint.ts] //// +//// [tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts] //// -=== reverseLimitedConstraint.ts === +=== reverseMappedTypeLimitedConstraint.ts === type XNumber_ = { x: number } >XNumber_ : { x: number; } >x : number diff --git a/tests/baselines/reference/revertedIntersection.errors.txt b/tests/baselines/reference/revertedIntersection.errors.txt deleted file mode 100644 index 09c14e18f81c8..0000000000000 --- a/tests/baselines/reference/revertedIntersection.errors.txt +++ /dev/null @@ -1,124 +0,0 @@ -revertedIntersection.ts(19,7): error TS2322: Type '"bar"' is not assignable to type '"foo"'. -revertedIntersection.ts(32,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ entry: "foo"; states: { a: { entry: "foo"; }; }; }'. -revertedIntersection.ts(43,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. -revertedIntersection.ts(60,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. - '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. -revertedIntersection.ts(64,49): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. -revertedIntersection.ts(70,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. - Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. - '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. -revertedIntersection.ts(75,36): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. -revertedIntersection.ts(88,12): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. - - -==== revertedIntersection.ts (8 errors) ==== - type StateConfig = { - entry?: TAction - states?: Record>; - }; - - type StateSchema = { - states?: Record; - }; - - declare function createMachine< - TConfig extends StateConfig, - TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, - >(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; - - const inferredParams1 = createMachine({ - entry: "foo", - states: { - a: { - entry: "bar", - ~~~~~ -!!! error TS2322: Type '"bar"' is not assignable to type '"foo"'. -!!! related TS6500 revertedIntersection.ts:2:3: The expected type comes from property 'entry' which is declared here on type 'StateConfig<"foo">' - }, - }, - extra: 12, - }); - - const inferredParams2 = createMachine({ - entry: "foo", - states: { - a: { - entry: "foo", - }, - }, - extra: 12, - ~~~~~ -!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ entry: "foo"; states: { a: { entry: "foo"; }; }; }'. - }); - - - // ----------------------------------------------------------------------------------------- - - const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; - - const checked = checkType<{x: number, y: string}>()({ - x: 1 as number, - y: "y", - z: "z", // undesirable property z is *not* allowed - ~ -!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. - }); - - checked; - // ^? - - // ----------------------------------------------------------------------------------------- - - interface Stuff { - field: number; - anotherField: string; - } - - function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { - if(Math.random() > 0.5) { - return s as T - } else { - return s - ~~~~~~ -!!! error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. -!!! error TS2322: '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. - } - } - - doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) - ~~~~~ -!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. - - function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { - if(Math.random() > 0.5) { - return arr as T[] - } else { - return arr - ~~~~~~ -!!! error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. -!!! error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. -!!! error TS2322: '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. - } - } - - doStuffWithStuffArr([ - { field: 1, anotherField: 'a', extra: 123 }, - ~~~~~ -!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. - ]) - - // ----------------------------------------------------------------------------------------- - - type XNumber = { x: number } - - declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; - - function bar(props: {x: number, y: string}) { - return foo(props); // no error because lack of excess property check by design - } - - foo({x: 1, y: 'foo'}); - ~ -!!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. - - foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design \ No newline at end of file diff --git a/tests/baselines/reference/revertedIntersection.symbols b/tests/baselines/reference/revertedIntersection.symbols deleted file mode 100644 index c134e304df02a..0000000000000 --- a/tests/baselines/reference/revertedIntersection.symbols +++ /dev/null @@ -1,257 +0,0 @@ -//// [tests/cases/compiler/revertedIntersection.ts] //// - -=== revertedIntersection.ts === -type StateConfig = { ->StateConfig : Symbol(StateConfig, Decl(revertedIntersection.ts, 0, 0)) ->TAction : Symbol(TAction, Decl(revertedIntersection.ts, 0, 17)) - - entry?: TAction ->entry : Symbol(entry, Decl(revertedIntersection.ts, 0, 44)) ->TAction : Symbol(TAction, Decl(revertedIntersection.ts, 0, 17)) - - states?: Record>; ->states : Symbol(states, Decl(revertedIntersection.ts, 1, 17)) ->Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) ->StateConfig : Symbol(StateConfig, Decl(revertedIntersection.ts, 0, 0)) ->TAction : Symbol(TAction, Decl(revertedIntersection.ts, 0, 17)) - -}; - -type StateSchema = { ->StateSchema : Symbol(StateSchema, Decl(revertedIntersection.ts, 3, 2)) - - states?: Record; ->states : Symbol(states, Decl(revertedIntersection.ts, 5, 20)) ->Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) ->StateSchema : Symbol(StateSchema, Decl(revertedIntersection.ts, 3, 2)) - -}; - -declare function createMachine< ->createMachine : Symbol(createMachine, Decl(revertedIntersection.ts, 7, 2)) - - TConfig extends StateConfig, ->TConfig : Symbol(TConfig, Decl(revertedIntersection.ts, 9, 31)) ->StateConfig : Symbol(StateConfig, Decl(revertedIntersection.ts, 0, 0)) ->TAction : Symbol(TAction, Decl(revertedIntersection.ts, 10, 39)) - - TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, ->TAction : Symbol(TAction, Decl(revertedIntersection.ts, 10, 39)) ->TConfig : Symbol(TConfig, Decl(revertedIntersection.ts, 9, 31)) ->TConfig : Symbol(TConfig, Decl(revertedIntersection.ts, 9, 31)) - ->(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; ->config : Symbol(config, Decl(revertedIntersection.ts, 12, 2)) ->K : Symbol(K, Decl(revertedIntersection.ts, 12, 13)) ->TConfig : Symbol(TConfig, Decl(revertedIntersection.ts, 9, 31)) ->StateConfig : Symbol(StateConfig, Decl(revertedIntersection.ts, 0, 0)) ->TAction : Symbol(TAction, Decl(revertedIntersection.ts, 10, 39)) ->TConfig : Symbol(TConfig, Decl(revertedIntersection.ts, 9, 31)) ->K : Symbol(K, Decl(revertedIntersection.ts, 12, 13)) ->TAction : Symbol(TAction, Decl(revertedIntersection.ts, 10, 39)) ->TConfig : Symbol(TConfig, Decl(revertedIntersection.ts, 9, 31)) - -const inferredParams1 = createMachine({ ->inferredParams1 : Symbol(inferredParams1, Decl(revertedIntersection.ts, 14, 5)) ->createMachine : Symbol(createMachine, Decl(revertedIntersection.ts, 7, 2)) - - entry: "foo", ->entry : Symbol(entry, Decl(revertedIntersection.ts, 14, 39)) - - states: { ->states : Symbol(states, Decl(revertedIntersection.ts, 15, 15)) - - a: { ->a : Symbol(a, Decl(revertedIntersection.ts, 16, 11)) - - entry: "bar", ->entry : Symbol(entry, Decl(revertedIntersection.ts, 17, 8)) - - }, - }, - extra: 12, ->extra : Symbol(extra, Decl(revertedIntersection.ts, 20, 4)) - -}); - -const inferredParams2 = createMachine({ ->inferredParams2 : Symbol(inferredParams2, Decl(revertedIntersection.ts, 24, 5)) ->createMachine : Symbol(createMachine, Decl(revertedIntersection.ts, 7, 2)) - - entry: "foo", ->entry : Symbol(entry, Decl(revertedIntersection.ts, 24, 39)) - - states: { ->states : Symbol(states, Decl(revertedIntersection.ts, 25, 15)) - - a: { ->a : Symbol(a, Decl(revertedIntersection.ts, 26, 11)) - - entry: "foo", ->entry : Symbol(entry, Decl(revertedIntersection.ts, 27, 8)) - - }, - }, - extra: 12, ->extra : Symbol(extra, Decl(revertedIntersection.ts, 30, 4)) - -}); - - -// ----------------------------------------------------------------------------------------- - -const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; ->checkType : Symbol(checkType, Decl(revertedIntersection.ts, 37, 5)) ->T : Symbol(T, Decl(revertedIntersection.ts, 37, 19)) ->U : Symbol(U, Decl(revertedIntersection.ts, 37, 28)) ->T : Symbol(T, Decl(revertedIntersection.ts, 37, 19)) ->value : Symbol(value, Decl(revertedIntersection.ts, 37, 41)) ->K : Symbol(K, Decl(revertedIntersection.ts, 37, 51)) ->U : Symbol(U, Decl(revertedIntersection.ts, 37, 28)) ->T : Symbol(T, Decl(revertedIntersection.ts, 37, 19)) ->U : Symbol(U, Decl(revertedIntersection.ts, 37, 28)) ->K : Symbol(K, Decl(revertedIntersection.ts, 37, 51)) ->value : Symbol(value, Decl(revertedIntersection.ts, 37, 41)) - -const checked = checkType<{x: number, y: string}>()({ ->checked : Symbol(checked, Decl(revertedIntersection.ts, 39, 5)) ->checkType : Symbol(checkType, Decl(revertedIntersection.ts, 37, 5)) ->x : Symbol(x, Decl(revertedIntersection.ts, 39, 27)) ->y : Symbol(y, Decl(revertedIntersection.ts, 39, 37)) - - x: 1 as number, ->x : Symbol(x, Decl(revertedIntersection.ts, 39, 53)) - - y: "y", ->y : Symbol(y, Decl(revertedIntersection.ts, 40, 17)) - - z: "z", // undesirable property z is *not* allowed ->z : Symbol(z, Decl(revertedIntersection.ts, 41, 9)) - -}); - -checked; ->checked : Symbol(checked, Decl(revertedIntersection.ts, 39, 5)) - - // ^? - -// ----------------------------------------------------------------------------------------- - -interface Stuff { ->Stuff : Symbol(Stuff, Decl(revertedIntersection.ts, 45, 8)) - - field: number; ->field : Symbol(Stuff.field, Decl(revertedIntersection.ts, 50, 17)) - - anotherField: string; ->anotherField : Symbol(Stuff.anotherField, Decl(revertedIntersection.ts, 51, 18)) -} - -function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { ->doStuffWithStuff : Symbol(doStuffWithStuff, Decl(revertedIntersection.ts, 53, 1)) ->T : Symbol(T, Decl(revertedIntersection.ts, 55, 26)) ->Stuff : Symbol(Stuff, Decl(revertedIntersection.ts, 45, 8)) ->s : Symbol(s, Decl(revertedIntersection.ts, 55, 43)) ->K : Symbol(K, Decl(revertedIntersection.ts, 55, 49)) ->T : Symbol(T, Decl(revertedIntersection.ts, 55, 26)) ->Stuff : Symbol(Stuff, Decl(revertedIntersection.ts, 45, 8)) ->T : Symbol(T, Decl(revertedIntersection.ts, 55, 26)) ->K : Symbol(K, Decl(revertedIntersection.ts, 55, 49)) ->T : Symbol(T, Decl(revertedIntersection.ts, 55, 26)) - - if(Math.random() > 0.5) { ->Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) ->Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) - - return s as T ->s : Symbol(s, Decl(revertedIntersection.ts, 55, 43)) ->T : Symbol(T, Decl(revertedIntersection.ts, 55, 26)) - - } else { - return s ->s : Symbol(s, Decl(revertedIntersection.ts, 55, 43)) - } -} - -doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) ->doStuffWithStuff : Symbol(doStuffWithStuff, Decl(revertedIntersection.ts, 53, 1)) ->field : Symbol(field, Decl(revertedIntersection.ts, 63, 18)) ->anotherField : Symbol(anotherField, Decl(revertedIntersection.ts, 63, 28)) ->extra : Symbol(extra, Decl(revertedIntersection.ts, 63, 47)) - -function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { ->doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(revertedIntersection.ts, 63, 61)) ->T : Symbol(T, Decl(revertedIntersection.ts, 65, 29)) ->Stuff : Symbol(Stuff, Decl(revertedIntersection.ts, 45, 8)) ->arr : Symbol(arr, Decl(revertedIntersection.ts, 65, 46)) ->K : Symbol(K, Decl(revertedIntersection.ts, 65, 54)) ->T : Symbol(T, Decl(revertedIntersection.ts, 65, 29)) ->Stuff : Symbol(Stuff, Decl(revertedIntersection.ts, 45, 8)) ->T : Symbol(T, Decl(revertedIntersection.ts, 65, 29)) ->K : Symbol(K, Decl(revertedIntersection.ts, 65, 54)) ->T : Symbol(T, Decl(revertedIntersection.ts, 65, 29)) - - if(Math.random() > 0.5) { ->Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) ->Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) - - return arr as T[] ->arr : Symbol(arr, Decl(revertedIntersection.ts, 65, 46)) ->T : Symbol(T, Decl(revertedIntersection.ts, 65, 29)) - - } else { - return arr ->arr : Symbol(arr, Decl(revertedIntersection.ts, 65, 46)) - } -} - -doStuffWithStuffArr([ ->doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(revertedIntersection.ts, 63, 61)) - - { field: 1, anotherField: 'a', extra: 123 }, ->field : Symbol(field, Decl(revertedIntersection.ts, 74, 5)) ->anotherField : Symbol(anotherField, Decl(revertedIntersection.ts, 74, 15)) ->extra : Symbol(extra, Decl(revertedIntersection.ts, 74, 34)) - -]) - -// ----------------------------------------------------------------------------------------- - -type XNumber = { x: number } ->XNumber : Symbol(XNumber, Decl(revertedIntersection.ts, 75, 2)) ->x : Symbol(x, Decl(revertedIntersection.ts, 79, 16)) - -declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; ->foo : Symbol(foo, Decl(revertedIntersection.ts, 79, 28)) ->T : Symbol(T, Decl(revertedIntersection.ts, 81, 21)) ->XNumber : Symbol(XNumber, Decl(revertedIntersection.ts, 75, 2)) ->props : Symbol(props, Decl(revertedIntersection.ts, 81, 40)) ->K : Symbol(K, Decl(revertedIntersection.ts, 81, 49)) ->T : Symbol(T, Decl(revertedIntersection.ts, 81, 21)) ->XNumber : Symbol(XNumber, Decl(revertedIntersection.ts, 75, 2)) ->T : Symbol(T, Decl(revertedIntersection.ts, 81, 21)) ->K : Symbol(K, Decl(revertedIntersection.ts, 81, 49)) - -function bar(props: {x: number, y: string}) { ->bar : Symbol(bar, Decl(revertedIntersection.ts, 81, 93)) ->props : Symbol(props, Decl(revertedIntersection.ts, 83, 13)) ->x : Symbol(x, Decl(revertedIntersection.ts, 83, 21)) ->y : Symbol(y, Decl(revertedIntersection.ts, 83, 31)) - - return foo(props); // no error because lack of excess property check by design ->foo : Symbol(foo, Decl(revertedIntersection.ts, 79, 28)) ->props : Symbol(props, Decl(revertedIntersection.ts, 83, 13)) -} - -foo({x: 1, y: 'foo'}); ->foo : Symbol(foo, Decl(revertedIntersection.ts, 79, 28)) ->x : Symbol(x, Decl(revertedIntersection.ts, 87, 5)) ->y : Symbol(y, Decl(revertedIntersection.ts, 87, 10)) - -foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design ->foo : Symbol(foo, Decl(revertedIntersection.ts, 79, 28)) ->x : Symbol(x, Decl(revertedIntersection.ts, 89, 9)) ->y : Symbol(y, Decl(revertedIntersection.ts, 89, 14)) - diff --git a/tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts b/tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts new file mode 100644 index 0000000000000..76bf659bcb06e --- /dev/null +++ b/tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts @@ -0,0 +1,180 @@ +// @strict: true + +type StateConfig = { + entry?: TAction + states?: Record>; +}; + +type StateSchema = { + states?: Record; +}; + +declare function createMachine< + TConfig extends StateConfig, + TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, +>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; + +const inferredParams1 = createMachine({ + entry: "foo", + states: { + a: { + entry: "bar", + }, + }, + extra: 12, +}); + +const inferredParams2 = createMachine({ + entry: "foo", + states: { + a: { + entry: "foo", + }, + }, + extra: 12, +}); + + +// ----------------------------------------------------------------------------------------- + +const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; + +const checked = checkType<{x: number, y: string}>()({ + x: 1 as number, + y: "y", + z: "z", // undesirable property z is *not* allowed +}); + +checked; + // ^? + +// ----------------------------------------------------------------------------------------- + +interface Stuff { + field: number; + anotherField: string; +} + +function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { + if(Math.random() > 0.5) { + return s as T + } else { + return s + } +} + +doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) + +function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { + if(Math.random() > 0.5) { + return arr as T[] + } else { + return arr + } +} + +doStuffWithStuffArr([ + { field: 1, anotherField: 'a', extra: 123 }, +]) + +// ----------------------------------------------------------------------------------------- + +type XNumber = { x: number } + +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; + +function bar(props: {x: number, y: string}) { + return foo(props); // no error because lack of excess property check by design +} + +foo({x: 1, y: 'foo'}); + +foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design + +// ----------------------------------------------------------------------------------------- + +type NoErrWithOptProps = { x: number, y?: string } + +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; + +baz({x: 1}); +baz({x: 1, z: 123}); +baz({x: 1, y: 'foo'}); +baz({x: 1, y: 'foo', z: 123}); + +// ----------------------------------------------------------------------------------------- + +interface WithNestedProp { + prop: string; + nested: { + prop: string; + } +} + +declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; + +const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); +// ^? + +// ----------------------------------------------------------------------------------------- + +type IsLiteralString = string extends T ? false : true; + +type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } + +interface ProvidedActor { + src: string; + logic: () => Promise; +} + +type DistributeActors = TActor extends { src: infer TSrc } + ? { + src: TSrc; + } + : never; + +interface MachineConfig { + types?: { + actors?: TActor; + }; + invoke: IsLiteralString extends true + ? DistributeActors + : { + src: string; + }; +} + +type NoExtra = { + [K in keyof T]: K extends keyof MachineConfig ? T[K] : never +} + +declare function createXMachine< + const TConfig extends MachineConfig, + TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, +>(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; + +const child = () => Promise.resolve("foo"); + +const config = createXMachine({ + // ^? + types: {} as { + actors: { + src: "str"; + logic: typeof child; + }; + }, + invoke: { + src: "str", + }, + extra: 10 +} as const); + +const config2 = createXMachine({ + invoke: { + src: "whatever", + }, + extra: 10 +}); + +config2 +// ^? diff --git a/tests/cases/compiler/reverseLimitedConstraint.ts b/tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts similarity index 100% rename from tests/cases/compiler/reverseLimitedConstraint.ts rename to tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts diff --git a/tests/cases/compiler/revertedIntersection.ts b/tests/cases/compiler/revertedIntersection.ts deleted file mode 100644 index 854c71cdbe7e4..0000000000000 --- a/tests/cases/compiler/revertedIntersection.ts +++ /dev/null @@ -1,92 +0,0 @@ -// @strict: true - -type StateConfig = { - entry?: TAction - states?: Record>; -}; - -type StateSchema = { - states?: Record; -}; - -declare function createMachine< - TConfig extends StateConfig, - TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, ->(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; - -const inferredParams1 = createMachine({ - entry: "foo", - states: { - a: { - entry: "bar", - }, - }, - extra: 12, -}); - -const inferredParams2 = createMachine({ - entry: "foo", - states: { - a: { - entry: "foo", - }, - }, - extra: 12, -}); - - -// ----------------------------------------------------------------------------------------- - -const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; - -const checked = checkType<{x: number, y: string}>()({ - x: 1 as number, - y: "y", - z: "z", // undesirable property z is *not* allowed -}); - -checked; - // ^? - -// ----------------------------------------------------------------------------------------- - -interface Stuff { - field: number; - anotherField: string; -} - -function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { - if(Math.random() > 0.5) { - return s as T - } else { - return s - } -} - -doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) - -function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { - if(Math.random() > 0.5) { - return arr as T[] - } else { - return arr - } -} - -doStuffWithStuffArr([ - { field: 1, anotherField: 'a', extra: 123 }, -]) - -// ----------------------------------------------------------------------------------------- - -type XNumber = { x: number } - -declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; - -function bar(props: {x: number, y: string}) { - return foo(props); // no error because lack of excess property check by design -} - -foo({x: 1, y: 'foo'}); - -foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design \ No newline at end of file From a48fd7c40f63ef5324b0eccb7cd65794d5e614d8 Mon Sep 17 00:00:00 2001 From: Andrea Simone Costa Date: Thu, 21 Sep 2023 11:25:37 +0200 Subject: [PATCH 5/8] update test --- ...appedTypeIntersectionConstraint.errors.txt | 52 +-- ...reverseMappedTypeIntersectionConstraint.js | 33 +- ...seMappedTypeIntersectionConstraint.symbols | 393 ++++++++---------- ...erseMappedTypeIntersectionConstraint.types | 71 ++-- ...reverseMappedTypeIntersectionConstraint.ts | 8 +- 5 files changed, 234 insertions(+), 323 deletions(-) diff --git a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt index 9b11707303d0a..ec7eab991b0ed 100644 --- a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt @@ -1,20 +1,20 @@ reverseMappedTypeIntersectionConstraint.ts(19,7): error TS2322: Type '"bar"' is not assignable to type '"foo"'. reverseMappedTypeIntersectionConstraint.ts(32,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ entry: "foo"; states: { a: { entry: "foo"; }; }; }'. reverseMappedTypeIntersectionConstraint.ts(43,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. -reverseMappedTypeIntersectionConstraint.ts(60,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. +reverseMappedTypeIntersectionConstraint.ts(59,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. -reverseMappedTypeIntersectionConstraint.ts(64,49): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. -reverseMappedTypeIntersectionConstraint.ts(70,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. +reverseMappedTypeIntersectionConstraint.ts(63,49): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. +reverseMappedTypeIntersectionConstraint.ts(69,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. -reverseMappedTypeIntersectionConstraint.ts(75,36): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. -reverseMappedTypeIntersectionConstraint.ts(88,12): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. -reverseMappedTypeIntersectionConstraint.ts(99,12): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; }'. -reverseMappedTypeIntersectionConstraint.ts(101,22): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; y: "foo"; }'. -reverseMappedTypeIntersectionConstraint.ts(114,67): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ prop: "foo"; nested: { prop: string; }; }'. -reverseMappedTypeIntersectionConstraint.ts(160,21): error TS2585: 'Promise' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. -reverseMappedTypeIntersectionConstraint.ts(173,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors?: { src: "str"; logic: () => any; } | undefined; } | undefined; invoke: { src: "str"; }; }'. -reverseMappedTypeIntersectionConstraint.ts(182,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ invoke: { src: "whatever"; }; }'. +reverseMappedTypeIntersectionConstraint.ts(74,36): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. +reverseMappedTypeIntersectionConstraint.ts(87,12): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. +reverseMappedTypeIntersectionConstraint.ts(98,12): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; }'. +reverseMappedTypeIntersectionConstraint.ts(100,22): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; y: "foo"; }'. +reverseMappedTypeIntersectionConstraint.ts(113,67): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ prop: "foo"; nested: { prop: string; }; }'. +reverseMappedTypeIntersectionConstraint.ts(152,21): error TS2585: 'Promise' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. +reverseMappedTypeIntersectionConstraint.ts(164,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors: { src: "str"; logic: () => any; }; }; invoke: { readonly src: "str"; }; }'. +reverseMappedTypeIntersectionConstraint.ts(171,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ invoke: { readonly src: "whatever"; }; }'. ==== reverseMappedTypeIntersectionConstraint.ts (14 errors) ==== @@ -30,7 +30,7 @@ reverseMappedTypeIntersectionConstraint.ts(182,3): error TS2353: Object literal declare function createMachine< TConfig extends StateConfig, TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, - >(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; + >(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; const inferredParams1 = createMachine({ entry: "foo", @@ -71,7 +71,6 @@ reverseMappedTypeIntersectionConstraint.ts(182,3): error TS2353: Object literal }); checked; - // ^? // ----------------------------------------------------------------------------------------- @@ -158,7 +157,6 @@ reverseMappedTypeIntersectionConstraint.ts(182,3): error TS2353: Object literal const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); ~~~~~ !!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ prop: "foo"; nested: { prop: string; }; }'. - // ^? // ----------------------------------------------------------------------------------------- @@ -171,12 +169,6 @@ reverseMappedTypeIntersectionConstraint.ts(182,3): error TS2353: Object literal logic: () => Promise; } - interface InferenceSource { - types?: { - actors?: TActor; - }; - } - type DistributeActors = TActor extends { src: infer TSrc } ? { src: TSrc; @@ -198,8 +190,8 @@ reverseMappedTypeIntersectionConstraint.ts(182,3): error TS2353: Object literal [K in keyof T]: K extends keyof MachineConfig ? T[K] : never } - declare function createMachine2< - TConfig extends MachineConfig, + declare function createXMachine< + const TConfig extends MachineConfig, TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, >(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; @@ -207,8 +199,7 @@ reverseMappedTypeIntersectionConstraint.ts(182,3): error TS2353: Object literal ~~~~~~~ !!! error TS2585: 'Promise' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. - const config = createMachine2({ - // ^? + const config = createXMachine({ types: {} as { actors: { src: "str"; @@ -220,20 +211,15 @@ reverseMappedTypeIntersectionConstraint.ts(182,3): error TS2353: Object literal }, extra: 10 ~~~~~ -!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors?: { src: "str"; logic: () => any; } | undefined; } | undefined; invoke: { src: "str"; }; }'. +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors: { src: "str"; logic: () => any; }; }; invoke: { readonly src: "str"; }; }'. }); - - - const config2 = createMachine2({ + const config2 = createXMachine({ invoke: { - src: "whatever" as const, + src: "whatever", }, extra: 10 ~~~~~ -!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ invoke: { src: "whatever"; }; }'. +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ invoke: { readonly src: "whatever"; }; }'. }); - - config2 - // ^? \ No newline at end of file diff --git a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js index 551fd92c14ead..a68576c793bf8 100644 --- a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js @@ -13,7 +13,7 @@ type StateSchema = { declare function createMachine< TConfig extends StateConfig, TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, ->(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; +>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; const inferredParams1 = createMachine({ entry: "foo", @@ -47,7 +47,6 @@ const checked = checkType<{x: number, y: string}>()({ }); checked; - // ^? // ----------------------------------------------------------------------------------------- @@ -115,7 +114,6 @@ interface WithNestedProp { declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); -// ^? // ----------------------------------------------------------------------------------------- @@ -128,12 +126,6 @@ interface ProvidedActor { logic: () => Promise; } -interface InferenceSource { - types?: { - actors?: TActor; - }; -} - type DistributeActors = TActor extends { src: infer TSrc } ? { src: TSrc; @@ -155,15 +147,14 @@ type NoExtra = { [K in keyof T]: K extends keyof MachineConfig ? T[K] : never } -declare function createMachine2< - TConfig extends MachineConfig, +declare function createXMachine< + const TConfig extends MachineConfig, TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, >(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; const child = () => Promise.resolve("foo"); -const config = createMachine2({ - // ^? +const config = createXMachine({ types: {} as { actors: { src: "str"; @@ -176,17 +167,12 @@ const config = createMachine2({ extra: 10 }); - - -const config2 = createMachine2({ +const config2 = createXMachine({ invoke: { - src: "whatever" as const, + src: "whatever", }, extra: 10 }); - -config2 -// ^? //// [reverseMappedTypeIntersectionConstraint.js] @@ -259,19 +245,16 @@ baz({ x: 1, y: 'foo' }); baz({ x: 1, y: 'foo', z: 123 }); var wnp = withNestedProp({ prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); var child = function () { return Promise.resolve("foo"); }; -var config = createMachine2({ - // ^? +var config = createXMachine({ types: {}, invoke: { src: "str", }, extra: 10 }); -var config2 = createMachine2({ +var config2 = createXMachine({ invoke: { src: "whatever", }, extra: 10 }); -config2; -// ^? diff --git a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols index 8b07ca8c6ebd3..12cb8664c8409 100644 --- a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols @@ -40,12 +40,11 @@ declare function createMachine< >TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) >TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) ->(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; +>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; >config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 12, 2)) >K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 12, 13)) >TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) >StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 0)) ->TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 10, 39)) >TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) >K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 12, 13)) >TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 10, 39)) @@ -133,31 +132,29 @@ const checked = checkType<{x: number, y: string}>()({ checked; >checked : Symbol(checked, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 5)) - // ^? - // ----------------------------------------------------------------------------------------- interface Stuff { >Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) field: number; ->field : Symbol(Stuff.field, Decl(reverseMappedTypeIntersectionConstraint.ts, 50, 17)) +>field : Symbol(Stuff.field, Decl(reverseMappedTypeIntersectionConstraint.ts, 49, 17)) anotherField: string; ->anotherField : Symbol(Stuff.anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 51, 18)) +>anotherField : Symbol(Stuff.anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 50, 18)) } function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { ->doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 53, 1)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 26)) +>doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 52, 1)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) >Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) ->s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 43)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 49)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 26)) +>s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 43)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 49)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) >Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 26)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 49)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 26)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 49)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) if(Math.random() > 0.5) { >Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) @@ -165,32 +162,32 @@ function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[ >random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) return s as T ->s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 43)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 26)) +>s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 43)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) } else { return s ->s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 55, 43)) +>s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 43)) } } doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) ->doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 53, 1)) ->field : Symbol(field, Decl(reverseMappedTypeIntersectionConstraint.ts, 63, 18)) ->anotherField : Symbol(anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 63, 28)) ->extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 63, 47)) +>doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 52, 1)) +>field : Symbol(field, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 18)) +>anotherField : Symbol(anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 28)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 47)) function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { ->doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeIntersectionConstraint.ts, 63, 61)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 29)) +>doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 61)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) >Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) ->arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 46)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 54)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 29)) +>arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 46)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 54)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) >Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 29)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 54)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 29)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 54)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) if(Math.random() > 0.5) { >Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) @@ -198,323 +195,297 @@ function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff >random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) return arr as T[] ->arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 46)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 29)) +>arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 46)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) } else { return arr ->arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 65, 46)) +>arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 46)) } } doStuffWithStuffArr([ ->doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeIntersectionConstraint.ts, 63, 61)) +>doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 61)) { field: 1, anotherField: 'a', extra: 123 }, ->field : Symbol(field, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 5)) ->anotherField : Symbol(anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 15)) ->extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 34)) +>field : Symbol(field, Decl(reverseMappedTypeIntersectionConstraint.ts, 73, 5)) +>anotherField : Symbol(anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 73, 15)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 73, 34)) ]) // ----------------------------------------------------------------------------------------- type XNumber = { x: number } ->XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 75, 2)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 79, 16)) +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 2)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 16)) declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; ->foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 79, 28)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 81, 21)) ->XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 75, 2)) ->props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 81, 40)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 81, 49)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 81, 21)) ->XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 75, 2)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 81, 21)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 81, 49)) +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 28)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 21)) +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 2)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 40)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 49)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 21)) +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 2)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 21)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 49)) function bar(props: {x: number, y: string}) { ->bar : Symbol(bar, Decl(reverseMappedTypeIntersectionConstraint.ts, 81, 93)) ->props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 83, 13)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 83, 21)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 83, 31)) +>bar : Symbol(bar, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 93)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 13)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 21)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 31)) return foo(props); // no error because lack of excess property check by design ->foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 79, 28)) ->props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 83, 13)) +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 28)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 13)) } foo({x: 1, y: 'foo'}); ->foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 79, 28)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 87, 5)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 87, 10)) +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 28)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 5)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 10)) foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design ->foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 79, 28)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 89, 9)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 89, 14)) +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 28)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 9)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 14)) // ----------------------------------------------------------------------------------------- type NoErrWithOptProps = { x: number, y?: string } ->NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 89, 27)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 26)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 37)) +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 27)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 26)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 37)) declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; ->baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 50)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 95, 21)) ->NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 89, 27)) ->props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 95, 50)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 95, 59)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 95, 21)) ->NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 89, 27)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 95, 21)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 95, 59)) +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 21)) +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 27)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 50)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 59)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 21)) +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 27)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 21)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 59)) baz({x: 1}); ->baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 50)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 97, 5)) +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 96, 5)) baz({x: 1, z: 123}); ->baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 50)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 98, 5)) ->z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 98, 10)) +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 97, 5)) +>z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 97, 10)) baz({x: 1, y: 'foo'}); ->baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 50)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 5)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 10)) +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 98, 5)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 98, 10)) baz({x: 1, y: 'foo', z: 123}); ->baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 50)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 100, 5)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 100, 10)) ->z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 100, 20)) +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 5)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 10)) +>z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 20)) // ----------------------------------------------------------------------------------------- interface WithNestedProp { ->WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 100, 30)) +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 30)) prop: string; ->prop : Symbol(WithNestedProp.prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 26)) +>prop : Symbol(WithNestedProp.prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 103, 26)) nested: { ->nested : Symbol(WithNestedProp.nested, Decl(reverseMappedTypeIntersectionConstraint.ts, 105, 15)) +>nested : Symbol(WithNestedProp.nested, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 15)) prop: string; ->prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 106, 11)) +>prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 105, 11)) } } declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; ->withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 109, 1)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 111, 32)) ->WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 100, 30)) ->props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 111, 58)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 111, 67)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 111, 32)) ->WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 100, 30)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 111, 32)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 111, 67)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 111, 32)) +>withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 108, 1)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 32)) +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 30)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 58)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 67)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 32)) +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 30)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 32)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 67)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 32)) const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); ->wnp : Symbol(wnp, Decl(reverseMappedTypeIntersectionConstraint.ts, 113, 5)) ->withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 109, 1)) ->prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 113, 28)) ->nested : Symbol(nested, Decl(reverseMappedTypeIntersectionConstraint.ts, 113, 40)) ->prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 113, 50)) ->extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 113, 65)) - -// ^? +>wnp : Symbol(wnp, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 5)) +>withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 108, 1)) +>prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 28)) +>nested : Symbol(nested, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 40)) +>prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 50)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 65)) // ----------------------------------------------------------------------------------------- type IsLiteralString = string extends T ? false : true; ->IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeIntersectionConstraint.ts, 113, 79)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 21)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 21)) +>IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 79)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 116, 21)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 116, 21)) type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } ->DeepWritable : Symbol(DeepWritable, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 73)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 18)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 18)) +>DeepWritable : Symbol(DeepWritable, Decl(reverseMappedTypeIntersectionConstraint.ts, 116, 73)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) >Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 18)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 61)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 18)) ->DeepWritable : Symbol(DeepWritable, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 73)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 18)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 61)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 61)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) +>DeepWritable : Symbol(DeepWritable, Decl(reverseMappedTypeIntersectionConstraint.ts, 116, 73)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 61)) interface ProvidedActor { ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 96)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) src: string; ->src : Symbol(ProvidedActor.src, Decl(reverseMappedTypeIntersectionConstraint.ts, 122, 25)) +>src : Symbol(ProvidedActor.src, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 25)) logic: () => Promise; ->logic : Symbol(ProvidedActor.logic, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 14)) +>logic : Symbol(ProvidedActor.logic, Decl(reverseMappedTypeIntersectionConstraint.ts, 121, 14)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) } -interface InferenceSource { ->InferenceSource : Symbol(InferenceSource, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 1)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 127, 26)) ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 96)) - - types?: { ->types : Symbol(InferenceSource.types, Decl(reverseMappedTypeIntersectionConstraint.ts, 127, 57)) - - actors?: TActor; ->actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 128, 11)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 127, 26)) - - }; -} - type DistributeActors = TActor extends { src: infer TSrc } ->DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 1)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 133, 22)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 133, 22)) ->src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 133, 48)) ->TSrc : Symbol(TSrc, Decl(reverseMappedTypeIntersectionConstraint.ts, 133, 59)) +>DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 1)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 22)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 22)) +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 48)) +>TSrc : Symbol(TSrc, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 59)) ? { src: TSrc; ->src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 134, 5)) ->TSrc : Symbol(TSrc, Decl(reverseMappedTypeIntersectionConstraint.ts, 133, 59)) +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 126, 5)) +>TSrc : Symbol(TSrc, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 59)) } : never; interface MachineConfig { ->MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 137, 10)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 139, 24)) ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 96)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 129, 10)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 24)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) types?: { ->types : Symbol(MachineConfig.types, Decl(reverseMappedTypeIntersectionConstraint.ts, 139, 55)) +>types : Symbol(MachineConfig.types, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 55)) actors?: TActor; ->actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 140, 11)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 139, 24)) +>actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 132, 11)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 24)) }; invoke: IsLiteralString extends true ->invoke : Symbol(MachineConfig.invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 142, 4)) ->IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeIntersectionConstraint.ts, 113, 79)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 139, 24)) +>invoke : Symbol(MachineConfig.invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 134, 4)) +>IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 79)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 24)) ? DistributeActors ->DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 1)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 139, 24)) +>DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 1)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 24)) : { src: string; ->src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 145, 7)) +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 137, 7)) }; } type NoExtra = { ->NoExtra : Symbol(NoExtra, Decl(reverseMappedTypeIntersectionConstraint.ts, 148, 1)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 150, 13)) +>NoExtra : Symbol(NoExtra, Decl(reverseMappedTypeIntersectionConstraint.ts, 140, 1)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 142, 13)) [K in keyof T]: K extends keyof MachineConfig ? T[K] : never ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 151, 3)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 150, 13)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 151, 3)) ->MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 137, 10)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 150, 13)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 151, 3)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 143, 3)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 142, 13)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 143, 3)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 129, 10)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 142, 13)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 143, 3)) } -declare function createMachine2< ->createMachine2 : Symbol(createMachine2, Decl(reverseMappedTypeIntersectionConstraint.ts, 152, 1)) +declare function createXMachine< +>createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 144, 1)) - TConfig extends MachineConfig, ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 32)) ->MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 137, 10)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 155, 40)) + const TConfig extends MachineConfig, +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 129, 10)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 147, 46)) TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 155, 40)) ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 96)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 32)) ->types : Symbol(types, Decl(reverseMappedTypeIntersectionConstraint.ts, 156, 50)) ->actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 156, 59)) ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 96)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 32)) ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 96)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 147, 46)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) +>types : Symbol(types, Decl(reverseMappedTypeIntersectionConstraint.ts, 148, 50)) +>actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 148, 59)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) >(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; ->config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 157, 2)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 157, 12)) ->MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 137, 10)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 32)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 32)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 157, 12)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 32)) +>config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 149, 2)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 149, 12)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 129, 10)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 149, 12)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) const child = () => Promise.resolve("foo"); ->child : Symbol(child, Decl(reverseMappedTypeIntersectionConstraint.ts, 159, 5)) +>child : Symbol(child, Decl(reverseMappedTypeIntersectionConstraint.ts, 151, 5)) -const config = createMachine2({ ->config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 161, 5)) ->createMachine2 : Symbol(createMachine2, Decl(reverseMappedTypeIntersectionConstraint.ts, 152, 1)) +const config = createXMachine({ +>config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 153, 5)) +>createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 144, 1)) - // ^? types: {} as { ->types : Symbol(types, Decl(reverseMappedTypeIntersectionConstraint.ts, 161, 31)) +>types : Symbol(types, Decl(reverseMappedTypeIntersectionConstraint.ts, 153, 31)) actors: { ->actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 163, 16)) +>actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 16)) src: "str"; ->src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 164, 13)) +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 155, 13)) logic: typeof child; ->logic : Symbol(logic, Decl(reverseMappedTypeIntersectionConstraint.ts, 165, 17)) ->child : Symbol(child, Decl(reverseMappedTypeIntersectionConstraint.ts, 159, 5)) +>logic : Symbol(logic, Decl(reverseMappedTypeIntersectionConstraint.ts, 156, 17)) +>child : Symbol(child, Decl(reverseMappedTypeIntersectionConstraint.ts, 151, 5)) }; }, invoke: { ->invoke : Symbol(invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 168, 4)) +>invoke : Symbol(invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 159, 4)) src: "str", ->src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 169, 11)) +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 160, 11)) }, extra: 10 ->extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 171, 4)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 162, 4)) }); - - -const config2 = createMachine2({ ->config2 : Symbol(config2, Decl(reverseMappedTypeIntersectionConstraint.ts, 177, 5)) ->createMachine2 : Symbol(createMachine2, Decl(reverseMappedTypeIntersectionConstraint.ts, 152, 1)) +const config2 = createXMachine({ +>config2 : Symbol(config2, Decl(reverseMappedTypeIntersectionConstraint.ts, 166, 5)) +>createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 144, 1)) invoke: { ->invoke : Symbol(invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 177, 32)) +>invoke : Symbol(invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 166, 32)) - src: "whatever" as const, ->src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 178, 11)) ->const : Symbol(const) + src: "whatever", +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 167, 11)) }, extra: 10 ->extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 180, 4)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 169, 4)) }); -config2 ->config2 : Symbol(config2, Decl(reverseMappedTypeIntersectionConstraint.ts, 177, 5)) - -// ^? - diff --git a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types index d8019a342cf72..43b568dd83d87 100644 --- a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types @@ -21,17 +21,17 @@ type StateSchema = { }; declare function createMachine< ->createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] +>createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] TConfig extends StateConfig, TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, ->(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; ->config : { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; } +>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; +>config : { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; } const inferredParams1 = createMachine({ >inferredParams1 : ["foo", StateConfig<"foo">] >createMachine({ entry: "foo", states: { a: { entry: "bar", }, }, extra: 12,}) : ["foo", StateConfig<"foo">] ->createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] +>createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] >{ entry: "foo", states: { a: { entry: "bar", }, }, extra: 12,} : { entry: "foo"; states: { a: { entry: "bar"; }; }; extra: number; } entry: "foo", @@ -59,9 +59,9 @@ const inferredParams1 = createMachine({ }); const inferredParams2 = createMachine({ ->inferredParams2 : ["foo", { entry: "foo"; states: { a: { entry: "foo"; }; }; extra: number; }] ->createMachine({ entry: "foo", states: { a: { entry: "foo", }, }, extra: 12,}) : ["foo", { entry: "foo"; states: { a: { entry: "foo"; }; }; extra: number; }] ->createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] +>inferredParams2 : ["foo", { entry: "foo"; states: { a: { entry: "foo"; }; }; }] +>createMachine({ entry: "foo", states: { a: { entry: "foo", }, }, extra: 12,}) : ["foo", { entry: "foo"; states: { a: { entry: "foo"; }; }; }] +>createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] >{ entry: "foo", states: { a: { entry: "foo", }, }, extra: 12,} : { entry: "foo"; states: { a: { entry: "foo"; }; }; extra: number; } entry: "foo", @@ -125,8 +125,6 @@ const checked = checkType<{x: number, y: string}>()({ checked; >checked : { x: number; y: "y"; } - // ^? - // ----------------------------------------------------------------------------------------- interface Stuff { @@ -160,7 +158,7 @@ function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[ } doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) ->doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) : { field: 1; anotherField: "a"; extra: number; } +>doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) : { field: 1; anotherField: "a"; } >doStuffWithStuff : (s: { [K in keyof T & keyof Stuff]: T[K]; }) => T >{ field: 1, anotherField: 'a', extra: 123 } : { field: 1; anotherField: "a"; extra: number; } >field : 1 @@ -193,7 +191,7 @@ function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff } doStuffWithStuffArr([ ->doStuffWithStuffArr([ { field: 1, anotherField: 'a', extra: 123 },]) : { field: 1; anotherField: "a"; extra: number; }[] +>doStuffWithStuffArr([ { field: 1, anotherField: 'a', extra: 123 },]) : { field: 1; anotherField: "a"; }[] >doStuffWithStuffArr : (arr: { [K in keyof T & keyof Stuff]: T[K]; }[]) => T[] >[ { field: 1, anotherField: 'a', extra: 123 },] : { field: 1; anotherField: "a"; extra: number; }[] @@ -328,8 +326,6 @@ const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); >extra : number >10 : 10 -// ^? - // ----------------------------------------------------------------------------------------- type IsLiteralString = string extends T ? false : true; @@ -348,16 +344,6 @@ interface ProvidedActor { >logic : () => Promise } -interface InferenceSource { - types?: { ->types : { actors?: TActor | undefined; } | undefined - - actors?: TActor; ->actors : TActor | undefined - - }; -} - type DistributeActors = TActor extends { src: infer TSrc } >DistributeActors : DistributeActors >src : TSrc @@ -394,10 +380,10 @@ type NoExtra = { [K in keyof T]: K extends keyof MachineConfig ? T[K] : never } -declare function createMachine2< ->createMachine2 : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor;}; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig +declare function createXMachine< +>createXMachine : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor;}; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig - TConfig extends MachineConfig, + const TConfig extends MachineConfig, TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, >types : { actors: ProvidedActor; } >actors : ProvidedActor @@ -414,13 +400,12 @@ const child = () => Promise.resolve("foo"); >resolve : any >"foo" : "foo" -const config = createMachine2({ ->config : MachineConfig<{ src: "str"; logic: typeof child; }> ->createMachine2({ // ^? types: {} as { actors: { src: "str"; logic: typeof child; }; }, invoke: { src: "str", }, extra: 10}) : MachineConfig<{ src: "str"; logic: typeof child; }> ->createMachine2 : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor; }; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig ->{ // ^? types: {} as { actors: { src: "str"; logic: typeof child; }; }, invoke: { src: "str", }, extra: 10} : { types: { actors: { src: "str"; logic: typeof child;}; }; invoke: { src: "str"; }; extra: number; } +const config = createXMachine({ +>config : { types: { actors: { src: "str"; logic: typeof child;}; }; invoke: { readonly src: "str"; }; } +>createXMachine({ types: {} as { actors: { src: "str"; logic: typeof child; }; }, invoke: { src: "str", }, extra: 10}) : { types: { actors: { src: "str"; logic: typeof child;}; }; invoke: { readonly src: "str"; }; } +>createXMachine : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor; }; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig +>{ types: {} as { actors: { src: "str"; logic: typeof child; }; }, invoke: { src: "str", }, extra: 10} : { types: { actors: { src: "str"; logic: typeof child;}; }; invoke: { src: "str"; }; extra: number; } - // ^? types: {} as { >types : { actors: { src: "str"; logic: typeof child;}; } >{} as { actors: { src: "str"; logic: typeof child; }; } : { actors: { src: "str"; logic: typeof child;}; } @@ -453,21 +438,18 @@ const config = createMachine2({ }); - - -const config2 = createMachine2({ ->config2 : { invoke: { src: "whatever"; }; } ->createMachine2({ invoke: { src: "whatever" as const, }, extra: 10}) : { invoke: { src: "whatever"; }; } ->createMachine2 : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor; }; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig ->{ invoke: { src: "whatever" as const, }, extra: 10} : { invoke: { src: "whatever"; }; extra: number; } +const config2 = createXMachine({ +>config2 : { invoke: { readonly src: "whatever"; }; } +>createXMachine({ invoke: { src: "whatever", }, extra: 10}) : { invoke: { readonly src: "whatever"; }; } +>createXMachine : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor; }; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig +>{ invoke: { src: "whatever", }, extra: 10} : { invoke: { src: "whatever"; }; extra: number; } invoke: { >invoke : { src: "whatever"; } ->{ src: "whatever" as const, } : { src: "whatever"; } +>{ src: "whatever", } : { src: "whatever"; } - src: "whatever" as const, + src: "whatever", >src : "whatever" ->"whatever" as const : "whatever" >"whatever" : "whatever" }, @@ -477,8 +459,3 @@ const config2 = createMachine2({ }); -config2 ->config2 : { invoke: { src: "whatever"; }; } - -// ^? - diff --git a/tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts b/tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts index 76bf659bcb06e..e565549791177 100644 --- a/tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts +++ b/tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts @@ -46,7 +46,6 @@ const checked = checkType<{x: number, y: string}>()({ }); checked; - // ^? // ----------------------------------------------------------------------------------------- @@ -114,7 +113,6 @@ interface WithNestedProp { declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); -// ^? // ----------------------------------------------------------------------------------------- @@ -156,7 +154,6 @@ declare function createXMachine< const child = () => Promise.resolve("foo"); const config = createXMachine({ - // ^? types: {} as { actors: { src: "str"; @@ -167,7 +164,7 @@ const config = createXMachine({ src: "str", }, extra: 10 -} as const); +}); const config2 = createXMachine({ invoke: { @@ -175,6 +172,3 @@ const config2 = createXMachine({ }, extra: 10 }); - -config2 -// ^? From 394a636531f3937b34b58f710686fcb7acfe0222 Mon Sep 17 00:00:00 2001 From: Andrea Simone Costa Date: Thu, 5 Oct 2023 17:10:27 +0200 Subject: [PATCH 6/8] add comments --- src/compiler/checker.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 991c32d7ce149..0c306cd109ad0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13523,6 +13523,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return instantiateType(instantiable, createTypeMapper([type.indexType, type.objectType], [getNumberLiteralType(0), createTupleType([replacement])])); } + // If the original mapped type had an intersection constraint, we extract its components, + // and we make an attempt to do so even if the intersection has been reduced to a union. + // This entire process allows us to possibly retrieve the filtering type literals. + // e.g. { [K in keyof U & "a" | "b" ] } -> "a" | "b" function getLimitedConstraint(type: ReverseMappedType) { const constraint = getConstraintTypeFromMappedType(type.mappedType); if (!(constraint.flags & TypeFlags.Union || constraint.flags & TypeFlags.Intersection)) { @@ -13545,6 +13549,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const members = createSymbolTable(); const limitedConstraint = getLimitedConstraint(type); for (const prop of getPropertiesOfType(type.source)) { + // In case of a reverse mapped type with an intersection constraint, if we were able to + // extract the filtering type literals we skip those properties, because they wouldn't + // get through the application of the mapped type anyway if (limitedConstraint) { const propertyNameType = getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique); if (!isTypeAssignableTo(propertyNameType, limitedConstraint)) { From 4c6b623df9f388228a7bac830cba45def345ef05 Mon Sep 17 00:00:00 2001 From: Andrea Simone Costa Date: Thu, 5 Oct 2023 22:43:28 +0200 Subject: [PATCH 7/8] enhance comment --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0c306cd109ad0..fe11a2fadaa09 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13550,8 +13550,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const limitedConstraint = getLimitedConstraint(type); for (const prop of getPropertiesOfType(type.source)) { // In case of a reverse mapped type with an intersection constraint, if we were able to - // extract the filtering type literals we skip those properties, because they wouldn't - // get through the application of the mapped type anyway + // extract the filtering type literals we skip those properties that are not assignable to them, + // because the extra properties wouldn't get through the application of the mapped type anyway if (limitedConstraint) { const propertyNameType = getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique); if (!isTypeAssignableTo(propertyNameType, limitedConstraint)) { From 21fae9e9b236c76d707af3525ec975171a8023a6 Mon Sep 17 00:00:00 2001 From: Andrea Simone Costa Date: Fri, 6 Oct 2023 11:20:21 +0200 Subject: [PATCH 8/8] enhance comment --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fe11a2fadaa09..9626c9d6fbce7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13523,10 +13523,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return instantiateType(instantiable, createTypeMapper([type.indexType, type.objectType], [getNumberLiteralType(0), createTupleType([replacement])])); } - // If the original mapped type had an intersection constraint, we extract its components, + // If the original mapped type had an intersection constraint we extract its components, // and we make an attempt to do so even if the intersection has been reduced to a union. // This entire process allows us to possibly retrieve the filtering type literals. - // e.g. { [K in keyof U & "a" | "b" ] } -> "a" | "b" + // e.g. { [K in keyof U & ("a" | "b") ] } -> "a" | "b" function getLimitedConstraint(type: ReverseMappedType) { const constraint = getConstraintTypeFromMappedType(type.mappedType); if (!(constraint.flags & TypeFlags.Union || constraint.flags & TypeFlags.Intersection)) {