Avoid pulling on setter type when only getter type is needed to break circularity (#47818)

This commit is contained in:
Andrew Branch 2022-02-09 10:56:29 -08:00 committed by GitHub
parent c06849ad16
commit 2cf5afd49e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 109 additions and 4 deletions

View File

@ -9511,11 +9511,12 @@ namespace ts {
const getter = getDeclarationOfKind<AccessorDeclaration>(symbol, SyntaxKind.GetAccessor);
const setter = getDeclarationOfKind<AccessorDeclaration>(symbol, SyntaxKind.SetAccessor);
const setterType = getAnnotatedAccessorType(setter);
// For write operations, prioritize type annotations on the setter
if (writing && setterType) {
return instantiateTypeIfNeeded(setterType, symbol);
if (writing) {
const setterType = getAnnotatedAccessorType(setter);
if (setterType) {
return instantiateTypeIfNeeded(setterType, symbol);
}
}
// Else defer to the getter type
@ -9533,6 +9534,7 @@ namespace ts {
}
// If the user didn't specify a return type, try to use the set-accessor's parameter type.
const setterType = getAnnotatedAccessorType(setter);
if (setterType) {
return setterType;
}

View File

@ -0,0 +1,16 @@
//// [mappedTypeCircularReferenceInAccessor.ts]
interface User {
firstName: string,
level: number,
get bestFriend(): User
set bestFriend(user: SerializablePartial<User>)
}
type FilteredKeys<T> = { [K in keyof T]: T[K] extends number ? K : T[K] extends string ? K : T[K] extends boolean ? K : never }[keyof T];
type SerializablePartial<T> = {
[K in FilteredKeys<T>]: T[K]
};
//// [mappedTypeCircularReferenceInAccessor.js]

View File

@ -0,0 +1,50 @@
=== tests/cases/compiler/mappedTypeCircularReferenceInAccessor.ts ===
interface User {
>User : Symbol(User, Decl(mappedTypeCircularReferenceInAccessor.ts, 0, 0))
firstName: string,
>firstName : Symbol(User.firstName, Decl(mappedTypeCircularReferenceInAccessor.ts, 0, 16))
level: number,
>level : Symbol(User.level, Decl(mappedTypeCircularReferenceInAccessor.ts, 1, 20))
get bestFriend(): User
>bestFriend : Symbol(User.bestFriend, Decl(mappedTypeCircularReferenceInAccessor.ts, 2, 16), Decl(mappedTypeCircularReferenceInAccessor.ts, 3, 24))
>User : Symbol(User, Decl(mappedTypeCircularReferenceInAccessor.ts, 0, 0))
set bestFriend(user: SerializablePartial<User>)
>bestFriend : Symbol(User.bestFriend, Decl(mappedTypeCircularReferenceInAccessor.ts, 2, 16), Decl(mappedTypeCircularReferenceInAccessor.ts, 3, 24))
>user : Symbol(user, Decl(mappedTypeCircularReferenceInAccessor.ts, 4, 17))
>SerializablePartial : Symbol(SerializablePartial, Decl(mappedTypeCircularReferenceInAccessor.ts, 7, 137))
>User : Symbol(User, Decl(mappedTypeCircularReferenceInAccessor.ts, 0, 0))
}
type FilteredKeys<T> = { [K in keyof T]: T[K] extends number ? K : T[K] extends string ? K : T[K] extends boolean ? K : never }[keyof T];
>FilteredKeys : Symbol(FilteredKeys, Decl(mappedTypeCircularReferenceInAccessor.ts, 5, 1))
>T : Symbol(T, Decl(mappedTypeCircularReferenceInAccessor.ts, 7, 18))
>K : Symbol(K, Decl(mappedTypeCircularReferenceInAccessor.ts, 7, 26))
>T : Symbol(T, Decl(mappedTypeCircularReferenceInAccessor.ts, 7, 18))
>T : Symbol(T, Decl(mappedTypeCircularReferenceInAccessor.ts, 7, 18))
>K : Symbol(K, Decl(mappedTypeCircularReferenceInAccessor.ts, 7, 26))
>K : Symbol(K, Decl(mappedTypeCircularReferenceInAccessor.ts, 7, 26))
>T : Symbol(T, Decl(mappedTypeCircularReferenceInAccessor.ts, 7, 18))
>K : Symbol(K, Decl(mappedTypeCircularReferenceInAccessor.ts, 7, 26))
>K : Symbol(K, Decl(mappedTypeCircularReferenceInAccessor.ts, 7, 26))
>T : Symbol(T, Decl(mappedTypeCircularReferenceInAccessor.ts, 7, 18))
>K : Symbol(K, Decl(mappedTypeCircularReferenceInAccessor.ts, 7, 26))
>K : Symbol(K, Decl(mappedTypeCircularReferenceInAccessor.ts, 7, 26))
>T : Symbol(T, Decl(mappedTypeCircularReferenceInAccessor.ts, 7, 18))
type SerializablePartial<T> = {
>SerializablePartial : Symbol(SerializablePartial, Decl(mappedTypeCircularReferenceInAccessor.ts, 7, 137))
>T : Symbol(T, Decl(mappedTypeCircularReferenceInAccessor.ts, 9, 25))
[K in FilteredKeys<T>]: T[K]
>K : Symbol(K, Decl(mappedTypeCircularReferenceInAccessor.ts, 10, 3))
>FilteredKeys : Symbol(FilteredKeys, Decl(mappedTypeCircularReferenceInAccessor.ts, 5, 1))
>T : Symbol(T, Decl(mappedTypeCircularReferenceInAccessor.ts, 9, 25))
>T : Symbol(T, Decl(mappedTypeCircularReferenceInAccessor.ts, 9, 25))
>K : Symbol(K, Decl(mappedTypeCircularReferenceInAccessor.ts, 10, 3))
};

View File

@ -0,0 +1,25 @@
=== tests/cases/compiler/mappedTypeCircularReferenceInAccessor.ts ===
interface User {
firstName: string,
>firstName : string
level: number,
>level : number
get bestFriend(): User
>bestFriend : User
set bestFriend(user: SerializablePartial<User>)
>bestFriend : User
>user : SerializablePartial<User>
}
type FilteredKeys<T> = { [K in keyof T]: T[K] extends number ? K : T[K] extends string ? K : T[K] extends boolean ? K : never }[keyof T];
>FilteredKeys : FilteredKeys<T>
type SerializablePartial<T> = {
>SerializablePartial : SerializablePartial<T>
[K in FilteredKeys<T>]: T[K]
};

View File

@ -0,0 +1,12 @@
interface User {
firstName: string,
level: number,
get bestFriend(): User
set bestFriend(user: SerializablePartial<User>)
}
type FilteredKeys<T> = { [K in keyof T]: T[K] extends number ? K : T[K] extends string ? K : T[K] extends boolean ? K : never }[keyof T];
type SerializablePartial<T> = {
[K in FilteredKeys<T>]: T[K]
};