mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-10 21:07:52 -05:00
Merge pull request #19741 from Microsoft/fixMappedTypeModifiers
Check combined mapped type modifiers
This commit is contained in:
@@ -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)) {
|
||||
|
||||
73
tests/baselines/reference/mappedTypes5.errors.txt
Normal file
73
tests/baselines/reference/mappedTypes5.errors.txt
Normal 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 };
|
||||
}
|
||||
|
||||
95
tests/baselines/reference/mappedTypes5.js
Normal file
95
tests/baselines/reference/mappedTypes5.js
Normal 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 };
|
||||
}
|
||||
279
tests/baselines/reference/mappedTypes5.symbols
Normal file
279
tests/baselines/reference/mappedTypes5.symbols
Normal 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))
|
||||
}
|
||||
|
||||
292
tests/baselines/reference/mappedTypes5.types
Normal file
292
tests/baselines/reference/mappedTypes5.types
Normal 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>
|
||||
}
|
||||
|
||||
62
tests/cases/conformance/types/mapped/mappedTypes5.ts
Normal file
62
tests/cases/conformance/types/mapped/mappedTypes5.ts
Normal 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 };
|
||||
}
|
||||
Reference in New Issue
Block a user