diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b0b014d598a..9546be1a27f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -520,6 +520,11 @@ namespace ts { Strict, } + const enum MappedTypeModifiers { + Readonly = 1 << 0, + Optional = 1 << 1, + } + const builtinGlobals = createSymbolTable(); builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol); @@ -5866,6 +5871,17 @@ namespace ts { return type.modifiersType; } + function getMappedTypeModifiers(type: MappedType): MappedTypeModifiers { + return (type.declaration.readonlyToken ? MappedTypeModifiers.Readonly : 0) | + (type.declaration.questionToken ? MappedTypeModifiers.Optional : 0); + } + + function getCombinedMappedTypeModifiers(type: MappedType): MappedTypeModifiers { + const modifiersType = getModifiersTypeFromMappedType(type); + return getMappedTypeModifiers(type) | + (isGenericMappedType(modifiersType) ? getMappedTypeModifiers(modifiersType) : 0); + } + function isPartialMappedType(type: Type) { return getObjectFlags(type) & ObjectFlags.Mapped && !!(type).declaration.questionToken; } @@ -9583,13 +9599,10 @@ namespace ts { // related to Y, where X' is an instantiation of X in which P is replaced with Q. Notice // that S and T are contra-variant whereas X and Y are co-variant. function mappedTypeRelatedTo(source: MappedType, target: MappedType, reportErrors: boolean): Ternary { - const sourceReadonly = !!source.declaration.readonlyToken; - const sourceOptional = !!source.declaration.questionToken; - const targetReadonly = !!target.declaration.readonlyToken; - const targetOptional = !!target.declaration.questionToken; - const modifiersRelated = relation === identityRelation ? - sourceReadonly === targetReadonly && sourceOptional === targetOptional : - relation === comparableRelation || !sourceOptional || targetOptional; + const modifiersRelated = relation === comparableRelation || ( + relation === identityRelation ? getMappedTypeModifiers(source) === getMappedTypeModifiers(target) : + !(getCombinedMappedTypeModifiers(source) & MappedTypeModifiers.Optional) || + getCombinedMappedTypeModifiers(target) & MappedTypeModifiers.Optional); if (modifiersRelated) { let result: Ternary; if (result = isRelatedTo(getConstraintTypeFromMappedType(target), getConstraintTypeFromMappedType(source), reportErrors)) { diff --git a/tests/baselines/reference/mappedTypes5.errors.txt b/tests/baselines/reference/mappedTypes5.errors.txt new file mode 100644 index 00000000000..d0c32cd1dd9 --- /dev/null +++ b/tests/baselines/reference/mappedTypes5.errors.txt @@ -0,0 +1,73 @@ +tests/cases/conformance/types/mapped/mappedTypes5.ts(6,9): error TS2322: Type 'Partial' is not assignable to type 'Readonly'. +tests/cases/conformance/types/mapped/mappedTypes5.ts(8,9): error TS2322: Type 'Partial>' is not assignable to type 'Readonly'. +tests/cases/conformance/types/mapped/mappedTypes5.ts(9,9): error TS2322: Type 'Readonly>' is not assignable to type 'Readonly'. + + +==== tests/cases/conformance/types/mapped/mappedTypes5.ts (3 errors) ==== + function f(p: Partial, r: Readonly, pr: Partial>, rp: Readonly>) { + let a1: Partial = p; + let a2: Partial = r; + let a3: Partial = pr; + let a4: Partial = rp; + let b1: Readonly = p; // Error + ~~ +!!! error TS2322: Type 'Partial' is not assignable to type 'Readonly'. + let b2: Readonly = r; + let b3: Readonly = pr; // Error + ~~ +!!! error TS2322: Type 'Partial>' is not assignable to type 'Readonly'. + let b4: Readonly = rp; // Error + ~~ +!!! error TS2322: Type 'Readonly>' is not assignable to type 'Readonly'. + let c1: Partial> = p; + let c2: Partial> = r; + let c3: Partial> = pr; + let c4: Partial> = rp; + let d1: Readonly> = p; + let d2: Readonly> = r; + let d3: Readonly> = pr; + let d4: Readonly> = rp; + } + + // Repro from #17682 + + type State = { + [key: string]: string | boolean | number | null; + }; + + type Args1 = { + readonly previous: Readonly>; + readonly current: Readonly>; + }; + + type Args2 = { + readonly previous: Partial>; + readonly current: Partial>; + }; + + function doit() { + let previous: Partial = Object.create(null); + let current: Partial = Object.create(null); + let args1: Args1 = { previous, current }; + let args2: Args2 = { previous, current }; + } + + type State2 = { foo: number, bar: string }; + + type Args3 = { + readonly previous: Readonly>; + readonly current: Readonly>; + }; + + type Args4 = { + readonly previous: Partial>; + readonly current: Partial>; + }; + + function doit2() { + let previous: Partial = Object.create(null); + let current: Partial = Object.create(null); + let args1: Args3 = { previous, current }; + let args2: Args4 = { previous, current }; + } + \ No newline at end of file diff --git a/tests/baselines/reference/mappedTypes5.js b/tests/baselines/reference/mappedTypes5.js new file mode 100644 index 00000000000..6f20b71ed7b --- /dev/null +++ b/tests/baselines/reference/mappedTypes5.js @@ -0,0 +1,95 @@ +//// [mappedTypes5.ts] +function f(p: Partial, r: Readonly, pr: Partial>, rp: Readonly>) { + let a1: Partial = p; + let a2: Partial = r; + let a3: Partial = pr; + let a4: Partial = rp; + let b1: Readonly = p; // Error + let b2: Readonly = r; + let b3: Readonly = pr; // Error + let b4: Readonly = rp; // Error + let c1: Partial> = p; + let c2: Partial> = r; + let c3: Partial> = pr; + let c4: Partial> = rp; + let d1: Readonly> = p; + let d2: Readonly> = r; + let d3: Readonly> = pr; + let d4: Readonly> = rp; +} + +// Repro from #17682 + +type State = { + [key: string]: string | boolean | number | null; +}; + +type Args1 = { + readonly previous: Readonly>; + readonly current: Readonly>; +}; + +type Args2 = { + readonly previous: Partial>; + readonly current: Partial>; +}; + +function doit() { + let previous: Partial = Object.create(null); + let current: Partial = Object.create(null); + let args1: Args1 = { previous, current }; + let args2: Args2 = { previous, current }; +} + +type State2 = { foo: number, bar: string }; + +type Args3 = { + readonly previous: Readonly>; + readonly current: Readonly>; +}; + +type Args4 = { + readonly previous: Partial>; + readonly current: Partial>; +}; + +function doit2() { + let previous: Partial = Object.create(null); + let current: Partial = Object.create(null); + let args1: Args3 = { previous, current }; + let args2: Args4 = { previous, current }; +} + + +//// [mappedTypes5.js] +"use strict"; +function f(p, r, pr, rp) { + var a1 = p; + var a2 = r; + var a3 = pr; + var a4 = rp; + var b1 = p; // Error + var b2 = r; + var b3 = pr; // Error + var b4 = rp; // Error + var c1 = p; + var c2 = r; + var c3 = pr; + var c4 = rp; + var d1 = p; + var d2 = r; + var d3 = pr; + var d4 = rp; +} +function doit() { + var previous = Object.create(null); + var current = Object.create(null); + var args1 = { previous: previous, current: current }; + var args2 = { previous: previous, current: current }; +} +function doit2() { + var previous = Object.create(null); + var current = Object.create(null); + var args1 = { previous: previous, current: current }; + var args2 = { previous: previous, current: current }; +} diff --git a/tests/baselines/reference/mappedTypes5.symbols b/tests/baselines/reference/mappedTypes5.symbols new file mode 100644 index 00000000000..7a499c4c4e9 --- /dev/null +++ b/tests/baselines/reference/mappedTypes5.symbols @@ -0,0 +1,279 @@ +=== tests/cases/conformance/types/mapped/mappedTypes5.ts === +function f(p: Partial, r: Readonly, pr: Partial>, rp: Readonly>) { +>f : Symbol(f, Decl(mappedTypes5.ts, 0, 0)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>p : Symbol(p, Decl(mappedTypes5.ts, 0, 14)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>r : Symbol(r, Decl(mappedTypes5.ts, 0, 28)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>pr : Symbol(pr, Decl(mappedTypes5.ts, 0, 44)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>rp : Symbol(rp, Decl(mappedTypes5.ts, 0, 70)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) + + let a1: Partial = p; +>a1 : Symbol(a1, Decl(mappedTypes5.ts, 1, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>p : Symbol(p, Decl(mappedTypes5.ts, 0, 14)) + + let a2: Partial = r; +>a2 : Symbol(a2, Decl(mappedTypes5.ts, 2, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>r : Symbol(r, Decl(mappedTypes5.ts, 0, 28)) + + let a3: Partial = pr; +>a3 : Symbol(a3, Decl(mappedTypes5.ts, 3, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>pr : Symbol(pr, Decl(mappedTypes5.ts, 0, 44)) + + let a4: Partial = rp; +>a4 : Symbol(a4, Decl(mappedTypes5.ts, 4, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>rp : Symbol(rp, Decl(mappedTypes5.ts, 0, 70)) + + let b1: Readonly = p; // Error +>b1 : Symbol(b1, Decl(mappedTypes5.ts, 5, 7)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>p : Symbol(p, Decl(mappedTypes5.ts, 0, 14)) + + let b2: Readonly = r; +>b2 : Symbol(b2, Decl(mappedTypes5.ts, 6, 7)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>r : Symbol(r, Decl(mappedTypes5.ts, 0, 28)) + + let b3: Readonly = pr; // Error +>b3 : Symbol(b3, Decl(mappedTypes5.ts, 7, 7)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>pr : Symbol(pr, Decl(mappedTypes5.ts, 0, 44)) + + let b4: Readonly = rp; // Error +>b4 : Symbol(b4, Decl(mappedTypes5.ts, 8, 7)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>rp : Symbol(rp, Decl(mappedTypes5.ts, 0, 70)) + + let c1: Partial> = p; +>c1 : Symbol(c1, Decl(mappedTypes5.ts, 9, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>p : Symbol(p, Decl(mappedTypes5.ts, 0, 14)) + + let c2: Partial> = r; +>c2 : Symbol(c2, Decl(mappedTypes5.ts, 10, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>r : Symbol(r, Decl(mappedTypes5.ts, 0, 28)) + + let c3: Partial> = pr; +>c3 : Symbol(c3, Decl(mappedTypes5.ts, 11, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>pr : Symbol(pr, Decl(mappedTypes5.ts, 0, 44)) + + let c4: Partial> = rp; +>c4 : Symbol(c4, Decl(mappedTypes5.ts, 12, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>rp : Symbol(rp, Decl(mappedTypes5.ts, 0, 70)) + + let d1: Readonly> = p; +>d1 : Symbol(d1, Decl(mappedTypes5.ts, 13, 7)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>p : Symbol(p, Decl(mappedTypes5.ts, 0, 14)) + + let d2: Readonly> = r; +>d2 : Symbol(d2, Decl(mappedTypes5.ts, 14, 7)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>r : Symbol(r, Decl(mappedTypes5.ts, 0, 28)) + + let d3: Readonly> = pr; +>d3 : Symbol(d3, Decl(mappedTypes5.ts, 15, 7)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>pr : Symbol(pr, Decl(mappedTypes5.ts, 0, 44)) + + let d4: Readonly> = rp; +>d4 : Symbol(d4, Decl(mappedTypes5.ts, 16, 7)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 0, 11)) +>rp : Symbol(rp, Decl(mappedTypes5.ts, 0, 70)) +} + +// Repro from #17682 + +type State = { +>State : Symbol(State, Decl(mappedTypes5.ts, 17, 1)) + + [key: string]: string | boolean | number | null; +>key : Symbol(key, Decl(mappedTypes5.ts, 22, 5)) + +}; + +type Args1 = { +>Args1 : Symbol(Args1, Decl(mappedTypes5.ts, 23, 2)) +>T : Symbol(T, Decl(mappedTypes5.ts, 25, 11)) +>State : Symbol(State, Decl(mappedTypes5.ts, 17, 1)) + + readonly previous: Readonly>; +>previous : Symbol(previous, Decl(mappedTypes5.ts, 25, 31)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 25, 11)) + + readonly current: Readonly>; +>current : Symbol(current, Decl(mappedTypes5.ts, 26, 44)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 25, 11)) + +}; + +type Args2 = { +>Args2 : Symbol(Args2, Decl(mappedTypes5.ts, 28, 2)) +>T : Symbol(T, Decl(mappedTypes5.ts, 30, 11)) +>State : Symbol(State, Decl(mappedTypes5.ts, 17, 1)) + + readonly previous: Partial>; +>previous : Symbol(previous, Decl(mappedTypes5.ts, 30, 31)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 30, 11)) + + readonly current: Partial>; +>current : Symbol(current, Decl(mappedTypes5.ts, 31, 44)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 30, 11)) + +}; + +function doit() { +>doit : Symbol(doit, Decl(mappedTypes5.ts, 33, 2)) +>T : Symbol(T, Decl(mappedTypes5.ts, 35, 14)) +>State : Symbol(State, Decl(mappedTypes5.ts, 17, 1)) + + let previous: Partial = Object.create(null); +>previous : Symbol(previous, Decl(mappedTypes5.ts, 36, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 35, 14)) +>Object.create : Symbol(ObjectConstructor.create, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>create : Symbol(ObjectConstructor.create, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + let current: Partial = Object.create(null); +>current : Symbol(current, Decl(mappedTypes5.ts, 37, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes5.ts, 35, 14)) +>Object.create : Symbol(ObjectConstructor.create, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>create : Symbol(ObjectConstructor.create, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + let args1: Args1 = { previous, current }; +>args1 : Symbol(args1, Decl(mappedTypes5.ts, 38, 7)) +>Args1 : Symbol(Args1, Decl(mappedTypes5.ts, 23, 2)) +>T : Symbol(T, Decl(mappedTypes5.ts, 35, 14)) +>previous : Symbol(previous, Decl(mappedTypes5.ts, 38, 27)) +>current : Symbol(current, Decl(mappedTypes5.ts, 38, 37)) + + let args2: Args2 = { previous, current }; +>args2 : Symbol(args2, Decl(mappedTypes5.ts, 39, 7)) +>Args2 : Symbol(Args2, Decl(mappedTypes5.ts, 28, 2)) +>T : Symbol(T, Decl(mappedTypes5.ts, 35, 14)) +>previous : Symbol(previous, Decl(mappedTypes5.ts, 39, 27)) +>current : Symbol(current, Decl(mappedTypes5.ts, 39, 37)) +} + +type State2 = { foo: number, bar: string }; +>State2 : Symbol(State2, Decl(mappedTypes5.ts, 40, 1)) +>foo : Symbol(foo, Decl(mappedTypes5.ts, 42, 15)) +>bar : Symbol(bar, Decl(mappedTypes5.ts, 42, 28)) + +type Args3 = { +>Args3 : Symbol(Args3, Decl(mappedTypes5.ts, 42, 43)) + + readonly previous: Readonly>; +>previous : Symbol(previous, Decl(mappedTypes5.ts, 44, 14)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>State2 : Symbol(State2, Decl(mappedTypes5.ts, 40, 1)) + + readonly current: Readonly>; +>current : Symbol(current, Decl(mappedTypes5.ts, 45, 49)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>State2 : Symbol(State2, Decl(mappedTypes5.ts, 40, 1)) + +}; + +type Args4 = { +>Args4 : Symbol(Args4, Decl(mappedTypes5.ts, 47, 2)) + + readonly previous: Partial>; +>previous : Symbol(previous, Decl(mappedTypes5.ts, 49, 14)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>State2 : Symbol(State2, Decl(mappedTypes5.ts, 40, 1)) + + readonly current: Partial>; +>current : Symbol(current, Decl(mappedTypes5.ts, 50, 49)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>State2 : Symbol(State2, Decl(mappedTypes5.ts, 40, 1)) + +}; + +function doit2() { +>doit2 : Symbol(doit2, Decl(mappedTypes5.ts, 52, 2)) + + let previous: Partial = Object.create(null); +>previous : Symbol(previous, Decl(mappedTypes5.ts, 55, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>State2 : Symbol(State2, Decl(mappedTypes5.ts, 40, 1)) +>Object.create : Symbol(ObjectConstructor.create, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>create : Symbol(ObjectConstructor.create, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + let current: Partial = Object.create(null); +>current : Symbol(current, Decl(mappedTypes5.ts, 56, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>State2 : Symbol(State2, Decl(mappedTypes5.ts, 40, 1)) +>Object.create : Symbol(ObjectConstructor.create, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>create : Symbol(ObjectConstructor.create, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + let args1: Args3 = { previous, current }; +>args1 : Symbol(args1, Decl(mappedTypes5.ts, 57, 7)) +>Args3 : Symbol(Args3, Decl(mappedTypes5.ts, 42, 43)) +>previous : Symbol(previous, Decl(mappedTypes5.ts, 57, 24)) +>current : Symbol(current, Decl(mappedTypes5.ts, 57, 34)) + + let args2: Args4 = { previous, current }; +>args2 : Symbol(args2, Decl(mappedTypes5.ts, 58, 7)) +>Args4 : Symbol(Args4, Decl(mappedTypes5.ts, 47, 2)) +>previous : Symbol(previous, Decl(mappedTypes5.ts, 58, 24)) +>current : Symbol(current, Decl(mappedTypes5.ts, 58, 34)) +} + diff --git a/tests/baselines/reference/mappedTypes5.types b/tests/baselines/reference/mappedTypes5.types new file mode 100644 index 00000000000..2cbc66523e2 --- /dev/null +++ b/tests/baselines/reference/mappedTypes5.types @@ -0,0 +1,292 @@ +=== tests/cases/conformance/types/mapped/mappedTypes5.ts === +function f(p: Partial, r: Readonly, pr: Partial>, rp: Readonly>) { +>f : (p: Partial, r: Readonly, pr: Partial>, rp: Readonly>) => void +>T : T +>p : Partial +>Partial : Partial +>T : T +>r : Readonly +>Readonly : Readonly +>T : T +>pr : Partial> +>Partial : Partial +>Readonly : Readonly +>T : T +>rp : Readonly> +>Readonly : Readonly +>Partial : Partial +>T : T + + let a1: Partial = p; +>a1 : Partial +>Partial : Partial +>T : T +>p : Partial + + let a2: Partial = r; +>a2 : Partial +>Partial : Partial +>T : T +>r : Readonly + + let a3: Partial = pr; +>a3 : Partial +>Partial : Partial +>T : T +>pr : Partial> + + let a4: Partial = rp; +>a4 : Partial +>Partial : Partial +>T : T +>rp : Readonly> + + let b1: Readonly = p; // Error +>b1 : Readonly +>Readonly : Readonly +>T : T +>p : Partial + + let b2: Readonly = r; +>b2 : Readonly +>Readonly : Readonly +>T : T +>r : Readonly + + let b3: Readonly = pr; // Error +>b3 : Readonly +>Readonly : Readonly +>T : T +>pr : Partial> + + let b4: Readonly = rp; // Error +>b4 : Readonly +>Readonly : Readonly +>T : T +>rp : Readonly> + + let c1: Partial> = p; +>c1 : Partial> +>Partial : Partial +>Readonly : Readonly +>T : T +>p : Partial + + let c2: Partial> = r; +>c2 : Partial> +>Partial : Partial +>Readonly : Readonly +>T : T +>r : Readonly + + let c3: Partial> = pr; +>c3 : Partial> +>Partial : Partial +>Readonly : Readonly +>T : T +>pr : Partial> + + let c4: Partial> = rp; +>c4 : Partial> +>Partial : Partial +>Readonly : Readonly +>T : T +>rp : Readonly> + + let d1: Readonly> = p; +>d1 : Readonly> +>Readonly : Readonly +>Partial : Partial +>T : T +>p : Partial + + let d2: Readonly> = r; +>d2 : Readonly> +>Readonly : Readonly +>Partial : Partial +>T : T +>r : Readonly + + let d3: Readonly> = pr; +>d3 : Readonly> +>Readonly : Readonly +>Partial : Partial +>T : T +>pr : Partial> + + let d4: Readonly> = rp; +>d4 : Readonly> +>Readonly : Readonly +>Partial : Partial +>T : T +>rp : Readonly> +} + +// Repro from #17682 + +type State = { +>State : State + + [key: string]: string | boolean | number | null; +>key : string +>null : null + +}; + +type Args1 = { +>Args1 : Args1 +>T : T +>State : State + + readonly previous: Readonly>; +>previous : Readonly> +>Readonly : Readonly +>Partial : Partial +>T : T + + readonly current: Readonly>; +>current : Readonly> +>Readonly : Readonly +>Partial : Partial +>T : T + +}; + +type Args2 = { +>Args2 : Args2 +>T : T +>State : State + + readonly previous: Partial>; +>previous : Partial> +>Partial : Partial +>Readonly : Readonly +>T : T + + readonly current: Partial>; +>current : Partial> +>Partial : Partial +>Readonly : Readonly +>T : T + +}; + +function doit() { +>doit : () => void +>T : T +>State : State + + let previous: Partial = Object.create(null); +>previous : Partial +>Partial : Partial +>T : T +>Object.create(null) : any +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } +>Object : ObjectConstructor +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } +>null : null + + let current: Partial = Object.create(null); +>current : Partial +>Partial : Partial +>T : T +>Object.create(null) : any +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } +>Object : ObjectConstructor +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } +>null : null + + let args1: Args1 = { previous, current }; +>args1 : Args1 +>Args1 : Args1 +>T : T +>{ previous, current } : { previous: Partial; current: Partial; } +>previous : Partial +>current : Partial + + let args2: Args2 = { previous, current }; +>args2 : Args2 +>Args2 : Args2 +>T : T +>{ previous, current } : { previous: Partial; current: Partial; } +>previous : Partial +>current : Partial +} + +type State2 = { foo: number, bar: string }; +>State2 : State2 +>foo : number +>bar : string + +type Args3 = { +>Args3 : Args3 + + readonly previous: Readonly>; +>previous : Readonly> +>Readonly : Readonly +>Partial : Partial +>State2 : State2 + + readonly current: Readonly>; +>current : Readonly> +>Readonly : Readonly +>Partial : Partial +>State2 : State2 + +}; + +type Args4 = { +>Args4 : Args4 + + readonly previous: Partial>; +>previous : Partial> +>Partial : Partial +>Readonly : Readonly +>State2 : State2 + + readonly current: Partial>; +>current : Partial> +>Partial : Partial +>Readonly : Readonly +>State2 : State2 + +}; + +function doit2() { +>doit2 : () => void + + let previous: Partial = Object.create(null); +>previous : Partial +>Partial : Partial +>State2 : State2 +>Object.create(null) : any +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } +>Object : ObjectConstructor +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } +>null : null + + let current: Partial = Object.create(null); +>current : Partial +>Partial : Partial +>State2 : State2 +>Object.create(null) : any +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } +>Object : ObjectConstructor +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } +>null : null + + let args1: Args3 = { previous, current }; +>args1 : Args3 +>Args3 : Args3 +>{ previous, current } : { previous: Partial; current: Partial; } +>previous : Partial +>current : Partial + + let args2: Args4 = { previous, current }; +>args2 : Args4 +>Args4 : Args4 +>{ previous, current } : { previous: Partial; current: Partial; } +>previous : Partial +>current : Partial +} + diff --git a/tests/cases/conformance/types/mapped/mappedTypes5.ts b/tests/cases/conformance/types/mapped/mappedTypes5.ts new file mode 100644 index 00000000000..38a010da0f5 --- /dev/null +++ b/tests/cases/conformance/types/mapped/mappedTypes5.ts @@ -0,0 +1,62 @@ +// @strict: true + +function f(p: Partial, r: Readonly, pr: Partial>, rp: Readonly>) { + let a1: Partial = p; + let a2: Partial = r; + let a3: Partial = pr; + let a4: Partial = rp; + let b1: Readonly = p; // Error + let b2: Readonly = r; + let b3: Readonly = pr; // Error + let b4: Readonly = rp; // Error + let c1: Partial> = p; + let c2: Partial> = r; + let c3: Partial> = pr; + let c4: Partial> = rp; + let d1: Readonly> = p; + let d2: Readonly> = r; + let d3: Readonly> = pr; + let d4: Readonly> = rp; +} + +// Repro from #17682 + +type State = { + [key: string]: string | boolean | number | null; +}; + +type Args1 = { + readonly previous: Readonly>; + readonly current: Readonly>; +}; + +type Args2 = { + readonly previous: Partial>; + readonly current: Partial>; +}; + +function doit() { + let previous: Partial = Object.create(null); + let current: Partial = Object.create(null); + let args1: Args1 = { previous, current }; + let args2: Args2 = { previous, current }; +} + +type State2 = { foo: number, bar: string }; + +type Args3 = { + readonly previous: Readonly>; + readonly current: Readonly>; +}; + +type Args4 = { + readonly previous: Partial>; + readonly current: Partial>; +}; + +function doit2() { + let previous: Partial = Object.create(null); + let current: Partial = Object.create(null); + let args1: Args3 = { previous, current }; + let args2: Args4 = { previous, current }; +}