Add more tests

This commit is contained in:
Anders Hejlsberg
2024-07-17 07:14:31 -07:00
parent 90ce450618
commit c8a66e06a9
4 changed files with 232 additions and 98 deletions

View File

@@ -14,8 +14,8 @@ enforceReadonly1.ts(53,11): error TS2430: Interface 'D2' incorrectly extends int
Property 'x' is 'readonly' in the source but not in the target.
enforceReadonly1.ts(61,7): error TS2415: Class 'D3' incorrectly extends base class 'B3'.
Property 'x' is 'readonly' in the source but not in the target.
enforceReadonly1.ts(100,3): error TS2540: Cannot assign to 'value' because it is a read-only property.
enforceReadonly1.ts(102,5): error TS2322: Type 'ImmutableValue<string>' is not assignable to type 'MutableValue<string>'.
enforceReadonly1.ts(119,3): error TS2540: Cannot assign to 'value' because it is a read-only property.
enforceReadonly1.ts(121,5): error TS2322: Type 'ImmutableValue<string>' is not assignable to type 'MutableValue<string>'.
Property 'value' is 'readonly' in the source but not in the target.
@@ -110,6 +110,25 @@ enforceReadonly1.ts(102,5): error TS2322: Type 'ImmutableValue<string>' is not a
readonly x = 1;
}
// readonly is not enforced in comparable relation
type Foo = {
readonly a: string | undefined;
readonly b: number | undefined;
}
type Bar = {
a: string;
}
function f5(foo: Foo, bar: Bar) {
return foo === bar;
}
function f6(a: string) {
return { a } as Foo;
}
// A const assertion means "as const as possible" without violating constraints
const x1 = { a: "hello", b: 42 };

View File

@@ -180,164 +180,204 @@ class D3 extends B3 { // Error
>x : Symbol(D3.x, Decl(enforceReadonly1.ts, 60, 21))
}
// readonly is not enforced in comparable relation
type Foo = {
>Foo : Symbol(Foo, Decl(enforceReadonly1.ts, 62, 1))
readonly a: string | undefined;
>a : Symbol(a, Decl(enforceReadonly1.ts, 66, 12))
readonly b: number | undefined;
>b : Symbol(b, Decl(enforceReadonly1.ts, 67, 35))
}
type Bar = {
>Bar : Symbol(Bar, Decl(enforceReadonly1.ts, 69, 1))
a: string;
>a : Symbol(a, Decl(enforceReadonly1.ts, 71, 12))
}
function f5(foo: Foo, bar: Bar) {
>f5 : Symbol(f5, Decl(enforceReadonly1.ts, 73, 1))
>foo : Symbol(foo, Decl(enforceReadonly1.ts, 75, 12))
>Foo : Symbol(Foo, Decl(enforceReadonly1.ts, 62, 1))
>bar : Symbol(bar, Decl(enforceReadonly1.ts, 75, 21))
>Bar : Symbol(Bar, Decl(enforceReadonly1.ts, 69, 1))
return foo === bar;
>foo : Symbol(foo, Decl(enforceReadonly1.ts, 75, 12))
>bar : Symbol(bar, Decl(enforceReadonly1.ts, 75, 21))
}
function f6(a: string) {
>f6 : Symbol(f6, Decl(enforceReadonly1.ts, 77, 1))
>a : Symbol(a, Decl(enforceReadonly1.ts, 79, 12))
return { a } as Foo;
>a : Symbol(a, Decl(enforceReadonly1.ts, 80, 12))
>Foo : Symbol(Foo, Decl(enforceReadonly1.ts, 62, 1))
}
// A const assertion means "as const as possible" without violating constraints
const x1 = { a: "hello", b: 42 };
>x1 : Symbol(x1, Decl(enforceReadonly1.ts, 66, 5))
>a : Symbol(a, Decl(enforceReadonly1.ts, 66, 12))
>b : Symbol(b, Decl(enforceReadonly1.ts, 66, 24))
>x1 : Symbol(x1, Decl(enforceReadonly1.ts, 85, 5))
>a : Symbol(a, Decl(enforceReadonly1.ts, 85, 12))
>b : Symbol(b, Decl(enforceReadonly1.ts, 85, 24))
const x2 = { a: "hello", b: 42 } as const;
>x2 : Symbol(x2, Decl(enforceReadonly1.ts, 67, 5))
>a : Symbol(a, Decl(enforceReadonly1.ts, 67, 12))
>b : Symbol(b, Decl(enforceReadonly1.ts, 67, 24))
>x2 : Symbol(x2, Decl(enforceReadonly1.ts, 86, 5))
>a : Symbol(a, Decl(enforceReadonly1.ts, 86, 12))
>b : Symbol(b, Decl(enforceReadonly1.ts, 86, 24))
>const : Symbol(const)
const y1: { a: string, b: number } = { a: "hello", b: 42 };
>y1 : Symbol(y1, Decl(enforceReadonly1.ts, 69, 5))
>a : Symbol(a, Decl(enforceReadonly1.ts, 69, 11))
>b : Symbol(b, Decl(enforceReadonly1.ts, 69, 22))
>a : Symbol(a, Decl(enforceReadonly1.ts, 69, 38))
>b : Symbol(b, Decl(enforceReadonly1.ts, 69, 50))
>y1 : Symbol(y1, Decl(enforceReadonly1.ts, 88, 5))
>a : Symbol(a, Decl(enforceReadonly1.ts, 88, 11))
>b : Symbol(b, Decl(enforceReadonly1.ts, 88, 22))
>a : Symbol(a, Decl(enforceReadonly1.ts, 88, 38))
>b : Symbol(b, Decl(enforceReadonly1.ts, 88, 50))
const y2: { a: string, b: number } = { a: "hello", b: 42 } as const;
>y2 : Symbol(y2, Decl(enforceReadonly1.ts, 70, 5))
>a : Symbol(a, Decl(enforceReadonly1.ts, 70, 11))
>b : Symbol(b, Decl(enforceReadonly1.ts, 70, 22))
>a : Symbol(a, Decl(enforceReadonly1.ts, 70, 38))
>b : Symbol(b, Decl(enforceReadonly1.ts, 70, 50))
>y2 : Symbol(y2, Decl(enforceReadonly1.ts, 89, 5))
>a : Symbol(a, Decl(enforceReadonly1.ts, 89, 11))
>b : Symbol(b, Decl(enforceReadonly1.ts, 89, 22))
>a : Symbol(a, Decl(enforceReadonly1.ts, 89, 38))
>b : Symbol(b, Decl(enforceReadonly1.ts, 89, 50))
>const : Symbol(const)
const y3: { a: string, readonly b: number } = { a: "hello", b: 42 };
>y3 : Symbol(y3, Decl(enforceReadonly1.ts, 71, 5))
>a : Symbol(a, Decl(enforceReadonly1.ts, 71, 11))
>b : Symbol(b, Decl(enforceReadonly1.ts, 71, 22))
>a : Symbol(a, Decl(enforceReadonly1.ts, 71, 47))
>b : Symbol(b, Decl(enforceReadonly1.ts, 71, 59))
>y3 : Symbol(y3, Decl(enforceReadonly1.ts, 90, 5))
>a : Symbol(a, Decl(enforceReadonly1.ts, 90, 11))
>b : Symbol(b, Decl(enforceReadonly1.ts, 90, 22))
>a : Symbol(a, Decl(enforceReadonly1.ts, 90, 47))
>b : Symbol(b, Decl(enforceReadonly1.ts, 90, 59))
const y4: Record<string, unknown> = { a: 1, b: 2 } as const;
>y4 : Symbol(y4, Decl(enforceReadonly1.ts, 72, 5))
>y4 : Symbol(y4, Decl(enforceReadonly1.ts, 91, 5))
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
>a : Symbol(a, Decl(enforceReadonly1.ts, 72, 37))
>b : Symbol(b, Decl(enforceReadonly1.ts, 72, 43))
>a : Symbol(a, Decl(enforceReadonly1.ts, 91, 37))
>b : Symbol(b, Decl(enforceReadonly1.ts, 91, 43))
>const : Symbol(const)
declare function f10<T>(obj: T): T;
>f10 : Symbol(f10, Decl(enforceReadonly1.ts, 72, 60))
>T : Symbol(T, Decl(enforceReadonly1.ts, 74, 21))
>obj : Symbol(obj, Decl(enforceReadonly1.ts, 74, 24))
>T : Symbol(T, Decl(enforceReadonly1.ts, 74, 21))
>T : Symbol(T, Decl(enforceReadonly1.ts, 74, 21))
>f10 : Symbol(f10, Decl(enforceReadonly1.ts, 91, 60))
>T : Symbol(T, Decl(enforceReadonly1.ts, 93, 21))
>obj : Symbol(obj, Decl(enforceReadonly1.ts, 93, 24))
>T : Symbol(T, Decl(enforceReadonly1.ts, 93, 21))
>T : Symbol(T, Decl(enforceReadonly1.ts, 93, 21))
declare function f11<const T>(obj: T): T;
>f11 : Symbol(f11, Decl(enforceReadonly1.ts, 74, 35))
>T : Symbol(T, Decl(enforceReadonly1.ts, 75, 21))
>obj : Symbol(obj, Decl(enforceReadonly1.ts, 75, 30))
>T : Symbol(T, Decl(enforceReadonly1.ts, 75, 21))
>T : Symbol(T, Decl(enforceReadonly1.ts, 75, 21))
>f11 : Symbol(f11, Decl(enforceReadonly1.ts, 93, 35))
>T : Symbol(T, Decl(enforceReadonly1.ts, 94, 21))
>obj : Symbol(obj, Decl(enforceReadonly1.ts, 94, 30))
>T : Symbol(T, Decl(enforceReadonly1.ts, 94, 21))
>T : Symbol(T, Decl(enforceReadonly1.ts, 94, 21))
declare function f12<const T extends { a: string, b: number }>(obj: T): T;
>f12 : Symbol(f12, Decl(enforceReadonly1.ts, 75, 41))
>T : Symbol(T, Decl(enforceReadonly1.ts, 76, 21))
>a : Symbol(a, Decl(enforceReadonly1.ts, 76, 38))
>b : Symbol(b, Decl(enforceReadonly1.ts, 76, 49))
>obj : Symbol(obj, Decl(enforceReadonly1.ts, 76, 63))
>T : Symbol(T, Decl(enforceReadonly1.ts, 76, 21))
>T : Symbol(T, Decl(enforceReadonly1.ts, 76, 21))
>f12 : Symbol(f12, Decl(enforceReadonly1.ts, 94, 41))
>T : Symbol(T, Decl(enforceReadonly1.ts, 95, 21))
>a : Symbol(a, Decl(enforceReadonly1.ts, 95, 38))
>b : Symbol(b, Decl(enforceReadonly1.ts, 95, 49))
>obj : Symbol(obj, Decl(enforceReadonly1.ts, 95, 63))
>T : Symbol(T, Decl(enforceReadonly1.ts, 95, 21))
>T : Symbol(T, Decl(enforceReadonly1.ts, 95, 21))
declare function f13<const T extends { a: string, readonly b: number }>(obj: T): T;
>f13 : Symbol(f13, Decl(enforceReadonly1.ts, 76, 74))
>T : Symbol(T, Decl(enforceReadonly1.ts, 77, 21))
>a : Symbol(a, Decl(enforceReadonly1.ts, 77, 38))
>b : Symbol(b, Decl(enforceReadonly1.ts, 77, 49))
>obj : Symbol(obj, Decl(enforceReadonly1.ts, 77, 72))
>T : Symbol(T, Decl(enforceReadonly1.ts, 77, 21))
>T : Symbol(T, Decl(enforceReadonly1.ts, 77, 21))
>f13 : Symbol(f13, Decl(enforceReadonly1.ts, 95, 74))
>T : Symbol(T, Decl(enforceReadonly1.ts, 96, 21))
>a : Symbol(a, Decl(enforceReadonly1.ts, 96, 38))
>b : Symbol(b, Decl(enforceReadonly1.ts, 96, 49))
>obj : Symbol(obj, Decl(enforceReadonly1.ts, 96, 72))
>T : Symbol(T, Decl(enforceReadonly1.ts, 96, 21))
>T : Symbol(T, Decl(enforceReadonly1.ts, 96, 21))
declare function f14<const T extends Record<string, unknown>>(obj: T): T;
>f14 : Symbol(f14, Decl(enforceReadonly1.ts, 77, 83))
>T : Symbol(T, Decl(enforceReadonly1.ts, 78, 21))
>f14 : Symbol(f14, Decl(enforceReadonly1.ts, 96, 83))
>T : Symbol(T, Decl(enforceReadonly1.ts, 97, 21))
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
>obj : Symbol(obj, Decl(enforceReadonly1.ts, 78, 62))
>T : Symbol(T, Decl(enforceReadonly1.ts, 78, 21))
>T : Symbol(T, Decl(enforceReadonly1.ts, 78, 21))
>obj : Symbol(obj, Decl(enforceReadonly1.ts, 97, 62))
>T : Symbol(T, Decl(enforceReadonly1.ts, 97, 21))
>T : Symbol(T, Decl(enforceReadonly1.ts, 97, 21))
declare function f15<const T extends Readonly<Record<string, unknown>>>(obj: T): T;
>f15 : Symbol(f15, Decl(enforceReadonly1.ts, 78, 73))
>T : Symbol(T, Decl(enforceReadonly1.ts, 79, 21))
>f15 : Symbol(f15, Decl(enforceReadonly1.ts, 97, 73))
>T : Symbol(T, Decl(enforceReadonly1.ts, 98, 21))
>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --))
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
>obj : Symbol(obj, Decl(enforceReadonly1.ts, 79, 72))
>T : Symbol(T, Decl(enforceReadonly1.ts, 79, 21))
>T : Symbol(T, Decl(enforceReadonly1.ts, 79, 21))
>obj : Symbol(obj, Decl(enforceReadonly1.ts, 98, 72))
>T : Symbol(T, Decl(enforceReadonly1.ts, 98, 21))
>T : Symbol(T, Decl(enforceReadonly1.ts, 98, 21))
f10({ a: "hello", b: 42 }); // { a: string; b: number; }
>f10 : Symbol(f10, Decl(enforceReadonly1.ts, 72, 60))
>a : Symbol(a, Decl(enforceReadonly1.ts, 81, 5))
>b : Symbol(b, Decl(enforceReadonly1.ts, 81, 17))
>f10 : Symbol(f10, Decl(enforceReadonly1.ts, 91, 60))
>a : Symbol(a, Decl(enforceReadonly1.ts, 100, 5))
>b : Symbol(b, Decl(enforceReadonly1.ts, 100, 17))
f11({ a: "hello", b: 42 }); // { readonly a: "hello"; readonly b: 42; }
>f11 : Symbol(f11, Decl(enforceReadonly1.ts, 74, 35))
>a : Symbol(a, Decl(enforceReadonly1.ts, 82, 5))
>b : Symbol(b, Decl(enforceReadonly1.ts, 82, 17))
>f11 : Symbol(f11, Decl(enforceReadonly1.ts, 93, 35))
>a : Symbol(a, Decl(enforceReadonly1.ts, 101, 5))
>b : Symbol(b, Decl(enforceReadonly1.ts, 101, 17))
f12({ a: "hello", b: 42 }); // { a: "hello"; b: 42; }
>f12 : Symbol(f12, Decl(enforceReadonly1.ts, 75, 41))
>a : Symbol(a, Decl(enforceReadonly1.ts, 83, 5))
>b : Symbol(b, Decl(enforceReadonly1.ts, 83, 17))
>f12 : Symbol(f12, Decl(enforceReadonly1.ts, 94, 41))
>a : Symbol(a, Decl(enforceReadonly1.ts, 102, 5))
>b : Symbol(b, Decl(enforceReadonly1.ts, 102, 17))
f13({ a: "hello", b: 42 }); // { a: "hello"; readonly b: 42; }
>f13 : Symbol(f13, Decl(enforceReadonly1.ts, 76, 74))
>a : Symbol(a, Decl(enforceReadonly1.ts, 84, 5))
>b : Symbol(b, Decl(enforceReadonly1.ts, 84, 17))
>f13 : Symbol(f13, Decl(enforceReadonly1.ts, 95, 74))
>a : Symbol(a, Decl(enforceReadonly1.ts, 103, 5))
>b : Symbol(b, Decl(enforceReadonly1.ts, 103, 17))
f14({ a: "hello", b: 42 }); // { a: "hello"; b: 42; }
>f14 : Symbol(f14, Decl(enforceReadonly1.ts, 77, 83))
>a : Symbol(a, Decl(enforceReadonly1.ts, 85, 5))
>b : Symbol(b, Decl(enforceReadonly1.ts, 85, 17))
>f14 : Symbol(f14, Decl(enforceReadonly1.ts, 96, 83))
>a : Symbol(a, Decl(enforceReadonly1.ts, 104, 5))
>b : Symbol(b, Decl(enforceReadonly1.ts, 104, 17))
f15({ a: "hello", b: 42 }); // { readonly a: "hello"; readonly b: 42; }
>f15 : Symbol(f15, Decl(enforceReadonly1.ts, 78, 73))
>a : Symbol(a, Decl(enforceReadonly1.ts, 86, 5))
>b : Symbol(b, Decl(enforceReadonly1.ts, 86, 17))
>f15 : Symbol(f15, Decl(enforceReadonly1.ts, 97, 73))
>a : Symbol(a, Decl(enforceReadonly1.ts, 105, 5))
>b : Symbol(b, Decl(enforceReadonly1.ts, 105, 17))
// https://github.com/microsoft/TypeScript/issues/13347
interface MutableValue<T> {
>MutableValue : Symbol(MutableValue, Decl(enforceReadonly1.ts, 86, 27))
>T : Symbol(T, Decl(enforceReadonly1.ts, 90, 23))
>MutableValue : Symbol(MutableValue, Decl(enforceReadonly1.ts, 105, 27))
>T : Symbol(T, Decl(enforceReadonly1.ts, 109, 23))
value: T;
>value : Symbol(MutableValue.value, Decl(enforceReadonly1.ts, 90, 27))
>T : Symbol(T, Decl(enforceReadonly1.ts, 90, 23))
>value : Symbol(MutableValue.value, Decl(enforceReadonly1.ts, 109, 27))
>T : Symbol(T, Decl(enforceReadonly1.ts, 109, 23))
}
interface ImmutableValue<T> {
>ImmutableValue : Symbol(ImmutableValue, Decl(enforceReadonly1.ts, 92, 1))
>T : Symbol(T, Decl(enforceReadonly1.ts, 94, 25))
>ImmutableValue : Symbol(ImmutableValue, Decl(enforceReadonly1.ts, 111, 1))
>T : Symbol(T, Decl(enforceReadonly1.ts, 113, 25))
readonly value: T;
>value : Symbol(ImmutableValue.value, Decl(enforceReadonly1.ts, 94, 29))
>T : Symbol(T, Decl(enforceReadonly1.ts, 94, 25))
>value : Symbol(ImmutableValue.value, Decl(enforceReadonly1.ts, 113, 29))
>T : Symbol(T, Decl(enforceReadonly1.ts, 113, 25))
}
let i: ImmutableValue<string> = { value: "hi" };
>i : Symbol(i, Decl(enforceReadonly1.ts, 98, 3))
>ImmutableValue : Symbol(ImmutableValue, Decl(enforceReadonly1.ts, 92, 1))
>value : Symbol(value, Decl(enforceReadonly1.ts, 98, 33))
>i : Symbol(i, Decl(enforceReadonly1.ts, 117, 3))
>ImmutableValue : Symbol(ImmutableValue, Decl(enforceReadonly1.ts, 111, 1))
>value : Symbol(value, Decl(enforceReadonly1.ts, 117, 33))
i.value = "Excellent, I can't change it"; // Error
>i.value : Symbol(ImmutableValue.value, Decl(enforceReadonly1.ts, 94, 29))
>i : Symbol(i, Decl(enforceReadonly1.ts, 98, 3))
>value : Symbol(ImmutableValue.value, Decl(enforceReadonly1.ts, 94, 29))
>i.value : Symbol(ImmutableValue.value, Decl(enforceReadonly1.ts, 113, 29))
>i : Symbol(i, Decl(enforceReadonly1.ts, 117, 3))
>value : Symbol(ImmutableValue.value, Decl(enforceReadonly1.ts, 113, 29))
let m: MutableValue<string> = i; // Error
>m : Symbol(m, Decl(enforceReadonly1.ts, 101, 3))
>MutableValue : Symbol(MutableValue, Decl(enforceReadonly1.ts, 86, 27))
>i : Symbol(i, Decl(enforceReadonly1.ts, 98, 3))
>m : Symbol(m, Decl(enforceReadonly1.ts, 120, 3))
>MutableValue : Symbol(MutableValue, Decl(enforceReadonly1.ts, 105, 27))
>i : Symbol(i, Decl(enforceReadonly1.ts, 117, 3))
m.value = "Oh dear, I can change it";
>m.value : Symbol(MutableValue.value, Decl(enforceReadonly1.ts, 90, 27))
>m : Symbol(m, Decl(enforceReadonly1.ts, 101, 3))
>value : Symbol(MutableValue.value, Decl(enforceReadonly1.ts, 90, 27))
>m.value : Symbol(MutableValue.value, Decl(enforceReadonly1.ts, 109, 27))
>m : Symbol(m, Decl(enforceReadonly1.ts, 120, 3))
>value : Symbol(MutableValue.value, Decl(enforceReadonly1.ts, 109, 27))

View File

@@ -265,6 +265,62 @@ class D3 extends B3 { // Error
> : ^
}
// readonly is not enforced in comparable relation
type Foo = {
>Foo : Foo
> : ^^^
readonly a: string | undefined;
>a : string | undefined
> : ^^^^^^^^^^^^^^^^^^
readonly b: number | undefined;
>b : number | undefined
> : ^^^^^^^^^^^^^^^^^^
}
type Bar = {
>Bar : Bar
> : ^^^
a: string;
>a : string
> : ^^^^^^
}
function f5(foo: Foo, bar: Bar) {
>f5 : (foo: Foo, bar: Bar) => boolean
> : ^ ^^ ^^ ^^ ^^^^^^^^^^^^
>foo : Foo
> : ^^^
>bar : Bar
> : ^^^
return foo === bar;
>foo === bar : boolean
> : ^^^^^^^
>foo : Foo
> : ^^^
>bar : Bar
> : ^^^
}
function f6(a: string) {
>f6 : (a: string) => Foo
> : ^ ^^ ^^^^^
>a : string
> : ^^^^^^
return { a } as Foo;
>{ a } as Foo : Foo
> : ^^^
>{ a } : { a: string; }
> : ^^^^^^^^^^^^^^
>a : string
> : ^^^^^^
}
// A const assertion means "as const as possible" without violating constraints
const x1 = { a: "hello", b: 42 };

View File

@@ -66,6 +66,25 @@ class D3 extends B3 { // Error
readonly x = 1;
}
// readonly is not enforced in comparable relation
type Foo = {
readonly a: string | undefined;
readonly b: number | undefined;
}
type Bar = {
a: string;
}
function f5(foo: Foo, bar: Bar) {
return foo === bar;
}
function f6(a: string) {
return { a } as Foo;
}
// A const assertion means "as const as possible" without violating constraints
const x1 = { a: "hello", b: 42 };