support generic variant setter (#55030)

This commit is contained in:
Zzzen 2023-08-30 05:11:33 +08:00 committed by GitHub
parent 23c9752367
commit c5f92d4150
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 174 additions and 3 deletions

View File

@ -19098,10 +19098,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function instantiateSymbol(symbol: Symbol, mapper: TypeMapper): Symbol {
const links = getSymbolLinks(symbol);
// If the type of the symbol is already resolved, and if that type could not possibly
// be affected by instantiation, simply return the symbol itself.
if (links.type && !couldContainTypeVariables(links.type)) {
// If the type of the symbol is already resolved, and if that type could not possibly
// be affected by instantiation, simply return the symbol itself.
return symbol;
if (!(symbol.flags & SymbolFlags.SetAccessor)) {
return symbol;
}
// If we're a setter, check writeType.
if (links.writeType && !couldContainTypeVariables(links.writeType)) {
return symbol;
}
}
if (getCheckFlags(symbol) & CheckFlags.Instantiated) {
// If symbol being instantiated is itself a instantiation, fetch the original target and combine the

View File

@ -0,0 +1,44 @@
//// [tests/cases/compiler/divergentAccessorsTypes7.ts] ////
//// [divergentAccessorsTypes7.ts]
class Test<S> {
constructor() {}
set value(value: string | ((item: S) => string)) {}
get value(): string {
return null!;
}
// -- Replacing the getter such that the getter/setter types match, removes the error:
// get value(): string | ((item: S) => string) {
// return null!;
// }
// -- Or, replacing the setter such that a concrete type is used, removes the error:
// set value(value: string | ((item: { property: string }) => string)) {}
}
const a = new Test<{
property: string
}>();
a.value = (item) => item.property
//// [divergentAccessorsTypes7.js]
var Test = /** @class */ (function () {
function Test() {
}
Object.defineProperty(Test.prototype, "value", {
get: function () {
return null;
},
set: function (value) { },
enumerable: false,
configurable: true
});
return Test;
}());
var a = new Test();
a.value = function (item) { return item.property; };

View File

@ -0,0 +1,48 @@
//// [tests/cases/compiler/divergentAccessorsTypes7.ts] ////
=== divergentAccessorsTypes7.ts ===
class Test<S> {
>Test : Symbol(Test, Decl(divergentAccessorsTypes7.ts, 0, 0))
>S : Symbol(S, Decl(divergentAccessorsTypes7.ts, 0, 11))
constructor() {}
set value(value: string | ((item: S) => string)) {}
>value : Symbol(Test.value, Decl(divergentAccessorsTypes7.ts, 1, 20), Decl(divergentAccessorsTypes7.ts, 3, 55))
>value : Symbol(value, Decl(divergentAccessorsTypes7.ts, 3, 14))
>item : Symbol(item, Decl(divergentAccessorsTypes7.ts, 3, 32))
>S : Symbol(S, Decl(divergentAccessorsTypes7.ts, 0, 11))
get value(): string {
>value : Symbol(Test.value, Decl(divergentAccessorsTypes7.ts, 1, 20), Decl(divergentAccessorsTypes7.ts, 3, 55))
return null!;
}
// -- Replacing the getter such that the getter/setter types match, removes the error:
// get value(): string | ((item: S) => string) {
// return null!;
// }
// -- Or, replacing the setter such that a concrete type is used, removes the error:
// set value(value: string | ((item: { property: string }) => string)) {}
}
const a = new Test<{
>a : Symbol(a, Decl(divergentAccessorsTypes7.ts, 18, 5))
>Test : Symbol(Test, Decl(divergentAccessorsTypes7.ts, 0, 0))
property: string
>property : Symbol(property, Decl(divergentAccessorsTypes7.ts, 18, 20))
}>();
a.value = (item) => item.property
>a.value : Symbol(Test.value, Decl(divergentAccessorsTypes7.ts, 1, 20), Decl(divergentAccessorsTypes7.ts, 3, 55))
>a : Symbol(a, Decl(divergentAccessorsTypes7.ts, 18, 5))
>value : Symbol(Test.value, Decl(divergentAccessorsTypes7.ts, 1, 20), Decl(divergentAccessorsTypes7.ts, 3, 55))
>item : Symbol(item, Decl(divergentAccessorsTypes7.ts, 22, 11))
>item.property : Symbol(property, Decl(divergentAccessorsTypes7.ts, 18, 20))
>item : Symbol(item, Decl(divergentAccessorsTypes7.ts, 22, 11))
>property : Symbol(property, Decl(divergentAccessorsTypes7.ts, 18, 20))

View File

@ -0,0 +1,50 @@
//// [tests/cases/compiler/divergentAccessorsTypes7.ts] ////
=== divergentAccessorsTypes7.ts ===
class Test<S> {
>Test : Test<S>
constructor() {}
set value(value: string | ((item: S) => string)) {}
>value : string
>value : string | ((item: S) => string)
>item : S
get value(): string {
>value : string
return null!;
>null! : null
}
// -- Replacing the getter such that the getter/setter types match, removes the error:
// get value(): string | ((item: S) => string) {
// return null!;
// }
// -- Or, replacing the setter such that a concrete type is used, removes the error:
// set value(value: string | ((item: { property: string }) => string)) {}
}
const a = new Test<{
>a : Test<{ property: string; }>
>new Test<{ property: string}>() : Test<{ property: string; }>
>Test : typeof Test
property: string
>property : string
}>();
a.value = (item) => item.property
>a.value = (item) => item.property : (item: { property: string; }) => string
>a.value : string | ((item: { property: string; }) => string)
>a : Test<{ property: string; }>
>value : string | ((item: { property: string; }) => string)
>(item) => item.property : (item: { property: string; }) => string
>item : { property: string; }
>item.property : string
>item : { property: string; }
>property : string

View File

@ -0,0 +1,23 @@
class Test<S> {
constructor() {}
set value(value: string | ((item: S) => string)) {}
get value(): string {
return null!;
}
// -- Replacing the getter such that the getter/setter types match, removes the error:
// get value(): string | ((item: S) => string) {
// return null!;
// }
// -- Or, replacing the setter such that a concrete type is used, removes the error:
// set value(value: string | ((item: { property: string }) => string)) {}
}
const a = new Test<{
property: string
}>();
a.value = (item) => item.property