Skip to content

Fix #33732 Consistent relation checking for property symbols with error reporting. #33828

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15866,7 +15866,7 @@ namespace ts {
if (unionParent && !result && targetIsOptional) {
result = isRelatedTo(source, undefinedType);
}
if (unionParent && !result && reportErrors) {
if (unionParent && !result && source.flags & TypeFlags.Union) {
// The easiest way to get the right errors here is to un-defer (which may be costly)
// If it turns out this is too costly too often, we can replicate the error handling logic within
// typeRelatedToSomeType without the discriminatable type branch (as that requires a manifest union
Expand Down
48 changes: 44 additions & 4 deletions tests/baselines/reference/excessPropertyCheckWithUnions.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ tests/cases/compiler/excessPropertyCheckWithUnions.ts(66,9): error TS2322: Type
Object literal may only specify known properties, and 'b' does not exist in type 'AN'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(87,5): error TS2322: Type '{ tag: "button"; type: "submit"; href: string; }' is not assignable to type 'Union'.
Object literal may only specify known properties, and 'href' does not exist in type 'Button'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(108,5): error TS2322: Type 'string' is not assignable to type 'IValue'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(113,67): error TS2322: Type 'string' is not assignable to type 'number'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(114,63): error TS2322: Type 'string' is not assignable to type 'number'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(148,5): error TS2322: Type 'string' is not assignable to type 'IValue'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(153,67): error TS2322: Type 'string' is not assignable to type 'number'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(154,63): error TS2322: Type 'string' is not assignable to type 'number'.


==== tests/cases/compiler/excessPropertyCheckWithUnions.ts (14 errors) ====
Expand Down Expand Up @@ -161,13 +161,53 @@ tests/cases/compiler/excessPropertyCheckWithUnions.ts(114,63): error TS2322: Typ
!!! error TS2322: Object literal may only specify known properties, and 'href' does not exist in type 'Button'.
};


// Repro from #33732

interface I1 {
prop1: string;
}

interface I2 {
prop2: string;
}

interface I3 extends Record<string, string> {

}

type Properties =
| { [key: string]: never }
| I1
| I2
| I3
;


declare const prop1: string;
declare const prop2: string | undefined;

function F1(_arg: { props: Properties }) { }
F1({
props: {
prop1,
prop2,
},
});

function F2(_props: Properties) { }
F2({
prop1,
prop2,
});

// Repro from #34611

interface IValue {
value: string
}

interface StringKeys {
interface StringKeys {
[propertyName: string]: IValue;
};

Expand Down
54 changes: 53 additions & 1 deletion tests/baselines/reference/excessPropertyCheckWithUnions.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,53 @@ const obj: Union = {
href: 'foo',
};


// Repro from #33732

interface I1 {
prop1: string;
}

interface I2 {
prop2: string;
}

interface I3 extends Record<string, string> {

}

type Properties =
| { [key: string]: never }
| I1
| I2
| I3
;


declare const prop1: string;
declare const prop2: string | undefined;

function F1(_arg: { props: Properties }) { }
F1({
props: {
prop1,
prop2,
},
});

function F2(_props: Properties) { }
F2({
prop1,
prop2,
});

// Repro from #34611

interface IValue {
value: string
}

interface StringKeys {
interface StringKeys {
[propertyName: string]: IValue;
};

Expand Down Expand Up @@ -170,6 +210,18 @@ var obj = {
// should have error here
href: 'foo'
};
function F1(_arg) { }
F1({
props: {
prop1: prop1,
prop2: prop2
}
});
function F2(_props) { }
F2({
prop1: prop1,
prop2: prop2
});
;
var dataSpecification = {
foo: "asdfsadffsd"
Expand Down
132 changes: 108 additions & 24 deletions tests/baselines/reference/excessPropertyCheckWithUnions.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -254,59 +254,143 @@ const obj: Union = {

};


// Repro from #33732

interface I1 {
>I1 : Symbol(I1, Decl(excessPropertyCheckWithUnions.ts, 87, 2))

prop1: string;
>prop1 : Symbol(I1.prop1, Decl(excessPropertyCheckWithUnions.ts, 92, 14))
}

interface I2 {
>I2 : Symbol(I2, Decl(excessPropertyCheckWithUnions.ts, 94, 1))

prop2: string;
>prop2 : Symbol(I2.prop2, Decl(excessPropertyCheckWithUnions.ts, 96, 14))
}

interface I3 extends Record<string, string> {
>I3 : Symbol(I3, Decl(excessPropertyCheckWithUnions.ts, 98, 1))
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))

}

type Properties =
>Properties : Symbol(Properties, Decl(excessPropertyCheckWithUnions.ts, 102, 1))

| { [key: string]: never }
>key : Symbol(key, Decl(excessPropertyCheckWithUnions.ts, 105, 9))

| I1
>I1 : Symbol(I1, Decl(excessPropertyCheckWithUnions.ts, 87, 2))

| I2
>I2 : Symbol(I2, Decl(excessPropertyCheckWithUnions.ts, 94, 1))

| I3
>I3 : Symbol(I3, Decl(excessPropertyCheckWithUnions.ts, 98, 1))

;


declare const prop1: string;
>prop1 : Symbol(prop1, Decl(excessPropertyCheckWithUnions.ts, 112, 13))

declare const prop2: string | undefined;
>prop2 : Symbol(prop2, Decl(excessPropertyCheckWithUnions.ts, 113, 13))

function F1(_arg: { props: Properties }) { }
>F1 : Symbol(F1, Decl(excessPropertyCheckWithUnions.ts, 113, 40))
>_arg : Symbol(_arg, Decl(excessPropertyCheckWithUnions.ts, 115, 12))
>props : Symbol(props, Decl(excessPropertyCheckWithUnions.ts, 115, 19))
>Properties : Symbol(Properties, Decl(excessPropertyCheckWithUnions.ts, 102, 1))

F1({
>F1 : Symbol(F1, Decl(excessPropertyCheckWithUnions.ts, 113, 40))

props: {
>props : Symbol(props, Decl(excessPropertyCheckWithUnions.ts, 116, 4))

prop1,
>prop1 : Symbol(prop1, Decl(excessPropertyCheckWithUnions.ts, 117, 12))

prop2,
>prop2 : Symbol(prop2, Decl(excessPropertyCheckWithUnions.ts, 118, 14))

},
});

function F2(_props: Properties) { }
>F2 : Symbol(F2, Decl(excessPropertyCheckWithUnions.ts, 121, 3))
>_props : Symbol(_props, Decl(excessPropertyCheckWithUnions.ts, 123, 12))
>Properties : Symbol(Properties, Decl(excessPropertyCheckWithUnions.ts, 102, 1))

F2({
>F2 : Symbol(F2, Decl(excessPropertyCheckWithUnions.ts, 121, 3))

prop1,
>prop1 : Symbol(prop1, Decl(excessPropertyCheckWithUnions.ts, 124, 4))

prop2,
>prop2 : Symbol(prop2, Decl(excessPropertyCheckWithUnions.ts, 125, 10))

});

// Repro from #34611

interface IValue {
>IValue : Symbol(IValue, Decl(excessPropertyCheckWithUnions.ts, 87, 2))
>IValue : Symbol(IValue, Decl(excessPropertyCheckWithUnions.ts, 127, 3))

value: string
>value : Symbol(IValue.value, Decl(excessPropertyCheckWithUnions.ts, 91, 18))
>value : Symbol(IValue.value, Decl(excessPropertyCheckWithUnions.ts, 131, 18))
}

interface StringKeys {
>StringKeys : Symbol(StringKeys, Decl(excessPropertyCheckWithUnions.ts, 93, 1))
interface StringKeys {
>StringKeys : Symbol(StringKeys, Decl(excessPropertyCheckWithUnions.ts, 133, 1))

[propertyName: string]: IValue;
>propertyName : Symbol(propertyName, Decl(excessPropertyCheckWithUnions.ts, 96, 5))
>IValue : Symbol(IValue, Decl(excessPropertyCheckWithUnions.ts, 87, 2))
>propertyName : Symbol(propertyName, Decl(excessPropertyCheckWithUnions.ts, 136, 5))
>IValue : Symbol(IValue, Decl(excessPropertyCheckWithUnions.ts, 127, 3))

};

interface NumberKeys {
>NumberKeys : Symbol(NumberKeys, Decl(excessPropertyCheckWithUnions.ts, 97, 2))
>NumberKeys : Symbol(NumberKeys, Decl(excessPropertyCheckWithUnions.ts, 137, 2))

[propertyName: number]: IValue;
>propertyName : Symbol(propertyName, Decl(excessPropertyCheckWithUnions.ts, 100, 5))
>IValue : Symbol(IValue, Decl(excessPropertyCheckWithUnions.ts, 87, 2))
>propertyName : Symbol(propertyName, Decl(excessPropertyCheckWithUnions.ts, 140, 5))
>IValue : Symbol(IValue, Decl(excessPropertyCheckWithUnions.ts, 127, 3))
}

type ObjectDataSpecification = StringKeys | NumberKeys;
>ObjectDataSpecification : Symbol(ObjectDataSpecification, Decl(excessPropertyCheckWithUnions.ts, 101, 1))
>StringKeys : Symbol(StringKeys, Decl(excessPropertyCheckWithUnions.ts, 93, 1))
>NumberKeys : Symbol(NumberKeys, Decl(excessPropertyCheckWithUnions.ts, 97, 2))
>ObjectDataSpecification : Symbol(ObjectDataSpecification, Decl(excessPropertyCheckWithUnions.ts, 141, 1))
>StringKeys : Symbol(StringKeys, Decl(excessPropertyCheckWithUnions.ts, 133, 1))
>NumberKeys : Symbol(NumberKeys, Decl(excessPropertyCheckWithUnions.ts, 137, 2))


const dataSpecification: ObjectDataSpecification = { // Error
>dataSpecification : Symbol(dataSpecification, Decl(excessPropertyCheckWithUnions.ts, 106, 5))
>ObjectDataSpecification : Symbol(ObjectDataSpecification, Decl(excessPropertyCheckWithUnions.ts, 101, 1))
>dataSpecification : Symbol(dataSpecification, Decl(excessPropertyCheckWithUnions.ts, 146, 5))
>ObjectDataSpecification : Symbol(ObjectDataSpecification, Decl(excessPropertyCheckWithUnions.ts, 141, 1))

foo: "asdfsadffsd"
>foo : Symbol(foo, Decl(excessPropertyCheckWithUnions.ts, 106, 52))
>foo : Symbol(foo, Decl(excessPropertyCheckWithUnions.ts, 146, 52))

};

// Repro from #34611

const obj1: { [x: string]: number } | { [x: number]: number } = { a: 'abc' }; // Error
>obj1 : Symbol(obj1, Decl(excessPropertyCheckWithUnions.ts, 112, 5))
>x : Symbol(x, Decl(excessPropertyCheckWithUnions.ts, 112, 15))
>x : Symbol(x, Decl(excessPropertyCheckWithUnions.ts, 112, 41))
>a : Symbol(a, Decl(excessPropertyCheckWithUnions.ts, 112, 65))
>obj1 : Symbol(obj1, Decl(excessPropertyCheckWithUnions.ts, 152, 5))
>x : Symbol(x, Decl(excessPropertyCheckWithUnions.ts, 152, 15))
>x : Symbol(x, Decl(excessPropertyCheckWithUnions.ts, 152, 41))
>a : Symbol(a, Decl(excessPropertyCheckWithUnions.ts, 152, 65))

const obj2: { [x: string]: number } | { a: number } = { a: 5, c: 'abc' }; // Error
>obj2 : Symbol(obj2, Decl(excessPropertyCheckWithUnions.ts, 113, 5))
>x : Symbol(x, Decl(excessPropertyCheckWithUnions.ts, 113, 15))
>a : Symbol(a, Decl(excessPropertyCheckWithUnions.ts, 113, 39))
>a : Symbol(a, Decl(excessPropertyCheckWithUnions.ts, 113, 55))
>c : Symbol(c, Decl(excessPropertyCheckWithUnions.ts, 113, 61))
>obj2 : Symbol(obj2, Decl(excessPropertyCheckWithUnions.ts, 153, 5))
>x : Symbol(x, Decl(excessPropertyCheckWithUnions.ts, 153, 15))
>a : Symbol(a, Decl(excessPropertyCheckWithUnions.ts, 153, 39))
>a : Symbol(a, Decl(excessPropertyCheckWithUnions.ts, 153, 55))
>c : Symbol(c, Decl(excessPropertyCheckWithUnions.ts, 153, 61))

Loading