Merge pull request #19741 from Microsoft/fixMappedTypeModifiers

Check combined mapped type modifiers
This commit is contained in:
Anders Hejlsberg
2017-11-06 09:35:28 -08:00
committed by GitHub
6 changed files with 821 additions and 7 deletions

View File

@@ -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(<MappedType>modifiersType) : 0);
}
function isPartialMappedType(type: Type) {
return getObjectFlags(type) & ObjectFlags.Mapped && !!(<MappedType>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(<MappedType>target), getConstraintTypeFromMappedType(<MappedType>source), reportErrors)) {

View File

@@ -0,0 +1,73 @@
tests/cases/conformance/types/mapped/mappedTypes5.ts(6,9): error TS2322: Type 'Partial<T>' is not assignable to type 'Readonly<T>'.
tests/cases/conformance/types/mapped/mappedTypes5.ts(8,9): error TS2322: Type 'Partial<Readonly<T>>' is not assignable to type 'Readonly<T>'.
tests/cases/conformance/types/mapped/mappedTypes5.ts(9,9): error TS2322: Type 'Readonly<Partial<T>>' is not assignable to type 'Readonly<T>'.
==== tests/cases/conformance/types/mapped/mappedTypes5.ts (3 errors) ====
function f<T>(p: Partial<T>, r: Readonly<T>, pr: Partial<Readonly<T>>, rp: Readonly<Partial<T>>) {
let a1: Partial<T> = p;
let a2: Partial<T> = r;
let a3: Partial<T> = pr;
let a4: Partial<T> = rp;
let b1: Readonly<T> = p; // Error
~~
!!! error TS2322: Type 'Partial<T>' is not assignable to type 'Readonly<T>'.
let b2: Readonly<T> = r;
let b3: Readonly<T> = pr; // Error
~~
!!! error TS2322: Type 'Partial<Readonly<T>>' is not assignable to type 'Readonly<T>'.
let b4: Readonly<T> = rp; // Error
~~
!!! error TS2322: Type 'Readonly<Partial<T>>' is not assignable to type 'Readonly<T>'.
let c1: Partial<Readonly<T>> = p;
let c2: Partial<Readonly<T>> = r;
let c3: Partial<Readonly<T>> = pr;
let c4: Partial<Readonly<T>> = rp;
let d1: Readonly<Partial<T>> = p;
let d2: Readonly<Partial<T>> = r;
let d3: Readonly<Partial<T>> = pr;
let d4: Readonly<Partial<T>> = rp;
}
// Repro from #17682
type State = {
[key: string]: string | boolean | number | null;
};
type Args1<T extends State> = {
readonly previous: Readonly<Partial<T>>;
readonly current: Readonly<Partial<T>>;
};
type Args2<T extends State> = {
readonly previous: Partial<Readonly<T>>;
readonly current: Partial<Readonly<T>>;
};
function doit<T extends State>() {
let previous: Partial<T> = Object.create(null);
let current: Partial<T> = Object.create(null);
let args1: Args1<T> = { previous, current };
let args2: Args2<T> = { previous, current };
}
type State2 = { foo: number, bar: string };
type Args3 = {
readonly previous: Readonly<Partial<State2>>;
readonly current: Readonly<Partial<State2>>;
};
type Args4 = {
readonly previous: Partial<Readonly<State2>>;
readonly current: Partial<Readonly<State2>>;
};
function doit2() {
let previous: Partial<State2> = Object.create(null);
let current: Partial<State2> = Object.create(null);
let args1: Args3 = { previous, current };
let args2: Args4 = { previous, current };
}

View File

@@ -0,0 +1,95 @@
//// [mappedTypes5.ts]
function f<T>(p: Partial<T>, r: Readonly<T>, pr: Partial<Readonly<T>>, rp: Readonly<Partial<T>>) {
let a1: Partial<T> = p;
let a2: Partial<T> = r;
let a3: Partial<T> = pr;
let a4: Partial<T> = rp;
let b1: Readonly<T> = p; // Error
let b2: Readonly<T> = r;
let b3: Readonly<T> = pr; // Error
let b4: Readonly<T> = rp; // Error
let c1: Partial<Readonly<T>> = p;
let c2: Partial<Readonly<T>> = r;
let c3: Partial<Readonly<T>> = pr;
let c4: Partial<Readonly<T>> = rp;
let d1: Readonly<Partial<T>> = p;
let d2: Readonly<Partial<T>> = r;
let d3: Readonly<Partial<T>> = pr;
let d4: Readonly<Partial<T>> = rp;
}
// Repro from #17682
type State = {
[key: string]: string | boolean | number | null;
};
type Args1<T extends State> = {
readonly previous: Readonly<Partial<T>>;
readonly current: Readonly<Partial<T>>;
};
type Args2<T extends State> = {
readonly previous: Partial<Readonly<T>>;
readonly current: Partial<Readonly<T>>;
};
function doit<T extends State>() {
let previous: Partial<T> = Object.create(null);
let current: Partial<T> = Object.create(null);
let args1: Args1<T> = { previous, current };
let args2: Args2<T> = { previous, current };
}
type State2 = { foo: number, bar: string };
type Args3 = {
readonly previous: Readonly<Partial<State2>>;
readonly current: Readonly<Partial<State2>>;
};
type Args4 = {
readonly previous: Partial<Readonly<State2>>;
readonly current: Partial<Readonly<State2>>;
};
function doit2() {
let previous: Partial<State2> = Object.create(null);
let current: Partial<State2> = 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 };
}

View File

@@ -0,0 +1,279 @@
=== tests/cases/conformance/types/mapped/mappedTypes5.ts ===
function f<T>(p: Partial<T>, r: Readonly<T>, pr: Partial<Readonly<T>>, rp: Readonly<Partial<T>>) {
>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<T> = 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<T> = 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<T> = 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<T> = 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<T> = 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<T> = 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<T> = 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<T> = 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<Readonly<T>> = 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<Readonly<T>> = 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<Readonly<T>> = 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<Readonly<T>> = 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<Partial<T>> = 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<Partial<T>> = 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<Partial<T>> = 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<Partial<T>> = 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<T extends State> = {
>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<Partial<T>>;
>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<Partial<T>>;
>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<T extends State> = {
>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<Readonly<T>>;
>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<Readonly<T>>;
>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<T extends State>() {
>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<T> = 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<T> = 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<T> = { 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<T> = { 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<Partial<State2>>;
>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<Partial<State2>>;
>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<Readonly<State2>>;
>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<Readonly<State2>>;
>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<State2> = 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<State2> = 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))
}

View File

@@ -0,0 +1,292 @@
=== tests/cases/conformance/types/mapped/mappedTypes5.ts ===
function f<T>(p: Partial<T>, r: Readonly<T>, pr: Partial<Readonly<T>>, rp: Readonly<Partial<T>>) {
>f : <T>(p: Partial<T>, r: Readonly<T>, pr: Partial<Readonly<T>>, rp: Readonly<Partial<T>>) => void
>T : T
>p : Partial<T>
>Partial : Partial<T>
>T : T
>r : Readonly<T>
>Readonly : Readonly<T>
>T : T
>pr : Partial<Readonly<T>>
>Partial : Partial<T>
>Readonly : Readonly<T>
>T : T
>rp : Readonly<Partial<T>>
>Readonly : Readonly<T>
>Partial : Partial<T>
>T : T
let a1: Partial<T> = p;
>a1 : Partial<T>
>Partial : Partial<T>
>T : T
>p : Partial<T>
let a2: Partial<T> = r;
>a2 : Partial<T>
>Partial : Partial<T>
>T : T
>r : Readonly<T>
let a3: Partial<T> = pr;
>a3 : Partial<T>
>Partial : Partial<T>
>T : T
>pr : Partial<Readonly<T>>
let a4: Partial<T> = rp;
>a4 : Partial<T>
>Partial : Partial<T>
>T : T
>rp : Readonly<Partial<T>>
let b1: Readonly<T> = p; // Error
>b1 : Readonly<T>
>Readonly : Readonly<T>
>T : T
>p : Partial<T>
let b2: Readonly<T> = r;
>b2 : Readonly<T>
>Readonly : Readonly<T>
>T : T
>r : Readonly<T>
let b3: Readonly<T> = pr; // Error
>b3 : Readonly<T>
>Readonly : Readonly<T>
>T : T
>pr : Partial<Readonly<T>>
let b4: Readonly<T> = rp; // Error
>b4 : Readonly<T>
>Readonly : Readonly<T>
>T : T
>rp : Readonly<Partial<T>>
let c1: Partial<Readonly<T>> = p;
>c1 : Partial<Readonly<T>>
>Partial : Partial<T>
>Readonly : Readonly<T>
>T : T
>p : Partial<T>
let c2: Partial<Readonly<T>> = r;
>c2 : Partial<Readonly<T>>
>Partial : Partial<T>
>Readonly : Readonly<T>
>T : T
>r : Readonly<T>
let c3: Partial<Readonly<T>> = pr;
>c3 : Partial<Readonly<T>>
>Partial : Partial<T>
>Readonly : Readonly<T>
>T : T
>pr : Partial<Readonly<T>>
let c4: Partial<Readonly<T>> = rp;
>c4 : Partial<Readonly<T>>
>Partial : Partial<T>
>Readonly : Readonly<T>
>T : T
>rp : Readonly<Partial<T>>
let d1: Readonly<Partial<T>> = p;
>d1 : Readonly<Partial<T>>
>Readonly : Readonly<T>
>Partial : Partial<T>
>T : T
>p : Partial<T>
let d2: Readonly<Partial<T>> = r;
>d2 : Readonly<Partial<T>>
>Readonly : Readonly<T>
>Partial : Partial<T>
>T : T
>r : Readonly<T>
let d3: Readonly<Partial<T>> = pr;
>d3 : Readonly<Partial<T>>
>Readonly : Readonly<T>
>Partial : Partial<T>
>T : T
>pr : Partial<Readonly<T>>
let d4: Readonly<Partial<T>> = rp;
>d4 : Readonly<Partial<T>>
>Readonly : Readonly<T>
>Partial : Partial<T>
>T : T
>rp : Readonly<Partial<T>>
}
// Repro from #17682
type State = {
>State : State
[key: string]: string | boolean | number | null;
>key : string
>null : null
};
type Args1<T extends State> = {
>Args1 : Args1<T>
>T : T
>State : State
readonly previous: Readonly<Partial<T>>;
>previous : Readonly<Partial<T>>
>Readonly : Readonly<T>
>Partial : Partial<T>
>T : T
readonly current: Readonly<Partial<T>>;
>current : Readonly<Partial<T>>
>Readonly : Readonly<T>
>Partial : Partial<T>
>T : T
};
type Args2<T extends State> = {
>Args2 : Args2<T>
>T : T
>State : State
readonly previous: Partial<Readonly<T>>;
>previous : Partial<Readonly<T>>
>Partial : Partial<T>
>Readonly : Readonly<T>
>T : T
readonly current: Partial<Readonly<T>>;
>current : Partial<Readonly<T>>
>Partial : Partial<T>
>Readonly : Readonly<T>
>T : T
};
function doit<T extends State>() {
>doit : <T extends State>() => void
>T : T
>State : State
let previous: Partial<T> = Object.create(null);
>previous : Partial<T>
>Partial : Partial<T>
>T : T
>Object.create(null) : any
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
>Object : ObjectConstructor
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
>null : null
let current: Partial<T> = Object.create(null);
>current : Partial<T>
>Partial : Partial<T>
>T : T
>Object.create(null) : any
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
>Object : ObjectConstructor
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
>null : null
let args1: Args1<T> = { previous, current };
>args1 : Args1<T>
>Args1 : Args1<T>
>T : T
>{ previous, current } : { previous: Partial<T>; current: Partial<T>; }
>previous : Partial<T>
>current : Partial<T>
let args2: Args2<T> = { previous, current };
>args2 : Args2<T>
>Args2 : Args2<T>
>T : T
>{ previous, current } : { previous: Partial<T>; current: Partial<T>; }
>previous : Partial<T>
>current : Partial<T>
}
type State2 = { foo: number, bar: string };
>State2 : State2
>foo : number
>bar : string
type Args3 = {
>Args3 : Args3
readonly previous: Readonly<Partial<State2>>;
>previous : Readonly<Partial<State2>>
>Readonly : Readonly<T>
>Partial : Partial<T>
>State2 : State2
readonly current: Readonly<Partial<State2>>;
>current : Readonly<Partial<State2>>
>Readonly : Readonly<T>
>Partial : Partial<T>
>State2 : State2
};
type Args4 = {
>Args4 : Args4
readonly previous: Partial<Readonly<State2>>;
>previous : Partial<Readonly<State2>>
>Partial : Partial<T>
>Readonly : Readonly<T>
>State2 : State2
readonly current: Partial<Readonly<State2>>;
>current : Partial<Readonly<State2>>
>Partial : Partial<T>
>Readonly : Readonly<T>
>State2 : State2
};
function doit2() {
>doit2 : () => void
let previous: Partial<State2> = Object.create(null);
>previous : Partial<State2>
>Partial : Partial<T>
>State2 : State2
>Object.create(null) : any
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
>Object : ObjectConstructor
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
>null : null
let current: Partial<State2> = Object.create(null);
>current : Partial<State2>
>Partial : Partial<T>
>State2 : State2
>Object.create(null) : any
>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
>Object : ObjectConstructor
>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any; }
>null : null
let args1: Args3 = { previous, current };
>args1 : Args3
>Args3 : Args3
>{ previous, current } : { previous: Partial<State2>; current: Partial<State2>; }
>previous : Partial<State2>
>current : Partial<State2>
let args2: Args4 = { previous, current };
>args2 : Args4
>Args4 : Args4
>{ previous, current } : { previous: Partial<State2>; current: Partial<State2>; }
>previous : Partial<State2>
>current : Partial<State2>
}

View File

@@ -0,0 +1,62 @@
// @strict: true
function f<T>(p: Partial<T>, r: Readonly<T>, pr: Partial<Readonly<T>>, rp: Readonly<Partial<T>>) {
let a1: Partial<T> = p;
let a2: Partial<T> = r;
let a3: Partial<T> = pr;
let a4: Partial<T> = rp;
let b1: Readonly<T> = p; // Error
let b2: Readonly<T> = r;
let b3: Readonly<T> = pr; // Error
let b4: Readonly<T> = rp; // Error
let c1: Partial<Readonly<T>> = p;
let c2: Partial<Readonly<T>> = r;
let c3: Partial<Readonly<T>> = pr;
let c4: Partial<Readonly<T>> = rp;
let d1: Readonly<Partial<T>> = p;
let d2: Readonly<Partial<T>> = r;
let d3: Readonly<Partial<T>> = pr;
let d4: Readonly<Partial<T>> = rp;
}
// Repro from #17682
type State = {
[key: string]: string | boolean | number | null;
};
type Args1<T extends State> = {
readonly previous: Readonly<Partial<T>>;
readonly current: Readonly<Partial<T>>;
};
type Args2<T extends State> = {
readonly previous: Partial<Readonly<T>>;
readonly current: Partial<Readonly<T>>;
};
function doit<T extends State>() {
let previous: Partial<T> = Object.create(null);
let current: Partial<T> = Object.create(null);
let args1: Args1<T> = { previous, current };
let args2: Args2<T> = { previous, current };
}
type State2 = { foo: number, bar: string };
type Args3 = {
readonly previous: Readonly<Partial<State2>>;
readonly current: Readonly<Partial<State2>>;
};
type Args4 = {
readonly previous: Partial<Readonly<State2>>;
readonly current: Partial<Readonly<State2>>;
};
function doit2() {
let previous: Partial<State2> = Object.create(null);
let current: Partial<State2> = Object.create(null);
let args1: Args3 = { previous, current };
let args2: Args4 = { previous, current };
}