mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-30 01:04:49 -05:00
Properly handle private/protected members in unions of object types (#38277)
* Property handle private/protected properties in unions of object types * Add regression test
This commit is contained in:
@@ -10539,7 +10539,6 @@ namespace ts {
|
||||
let propSet: Map<Symbol> | undefined;
|
||||
let indexTypes: Type[] | undefined;
|
||||
const isUnion = containingType.flags & TypeFlags.Union;
|
||||
const excludeModifiers = isUnion ? ModifierFlags.NonPublicAccessibilityModifier : 0;
|
||||
// Flags we want to propagate to the result if they exist in all source symbols
|
||||
let optionalFlag = isUnion ? SymbolFlags.None : SymbolFlags.Optional;
|
||||
let syntheticFlag = CheckFlags.SyntheticMethod;
|
||||
@@ -10549,7 +10548,7 @@ namespace ts {
|
||||
if (!(type === errorType || type.flags & TypeFlags.Never)) {
|
||||
const prop = getPropertyOfType(type, name);
|
||||
const modifiers = prop ? getDeclarationModifierFlagsFromSymbol(prop) : 0;
|
||||
if (prop && !(modifiers & excludeModifiers)) {
|
||||
if (prop) {
|
||||
if (isUnion) {
|
||||
optionalFlag |= (prop.flags & SymbolFlags.Optional);
|
||||
}
|
||||
@@ -10594,7 +10593,9 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!singleProp) {
|
||||
if (!singleProp || isUnion && (propSet || checkFlags & CheckFlags.Partial) && checkFlags & (CheckFlags.ContainsPrivate | CheckFlags.ContainsProtected)) {
|
||||
// No property was found, or, in a union, a property has a private or protected declaration in one
|
||||
// constituent, but is missing or has a different declaration in another constituent.
|
||||
return undefined;
|
||||
}
|
||||
if (!propSet && !(checkFlags & CheckFlags.ReadPartial) && !indexTypes) {
|
||||
|
||||
24
tests/baselines/reference/privatePropertyInUnion.js
Normal file
24
tests/baselines/reference/privatePropertyInUnion.js
Normal file
@@ -0,0 +1,24 @@
|
||||
//// [privatePropertyInUnion.ts]
|
||||
// Repro from #38236
|
||||
|
||||
type Type = string | object;
|
||||
|
||||
class SyncableObject {
|
||||
private foo: unknown;
|
||||
}
|
||||
|
||||
interface SyncableRef<T extends ISyncableObject> {}
|
||||
|
||||
interface ISyncableObject<T = object> extends SyncableObject {}
|
||||
|
||||
type __ValueDescriptorType<T extends string | object> = T extends ISyncableObject ? SyncableRef<T> : T;
|
||||
|
||||
|
||||
//// [privatePropertyInUnion.js]
|
||||
"use strict";
|
||||
// Repro from #38236
|
||||
var SyncableObject = /** @class */ (function () {
|
||||
function SyncableObject() {
|
||||
}
|
||||
return SyncableObject;
|
||||
}());
|
||||
32
tests/baselines/reference/privatePropertyInUnion.symbols
Normal file
32
tests/baselines/reference/privatePropertyInUnion.symbols
Normal file
@@ -0,0 +1,32 @@
|
||||
=== tests/cases/compiler/privatePropertyInUnion.ts ===
|
||||
// Repro from #38236
|
||||
|
||||
type Type = string | object;
|
||||
>Type : Symbol(Type, Decl(privatePropertyInUnion.ts, 0, 0))
|
||||
|
||||
class SyncableObject {
|
||||
>SyncableObject : Symbol(SyncableObject, Decl(privatePropertyInUnion.ts, 2, 28))
|
||||
|
||||
private foo: unknown;
|
||||
>foo : Symbol(SyncableObject.foo, Decl(privatePropertyInUnion.ts, 4, 22))
|
||||
}
|
||||
|
||||
interface SyncableRef<T extends ISyncableObject> {}
|
||||
>SyncableRef : Symbol(SyncableRef, Decl(privatePropertyInUnion.ts, 6, 1))
|
||||
>T : Symbol(T, Decl(privatePropertyInUnion.ts, 8, 22))
|
||||
>ISyncableObject : Symbol(ISyncableObject, Decl(privatePropertyInUnion.ts, 8, 51))
|
||||
|
||||
interface ISyncableObject<T = object> extends SyncableObject {}
|
||||
>ISyncableObject : Symbol(ISyncableObject, Decl(privatePropertyInUnion.ts, 8, 51))
|
||||
>T : Symbol(T, Decl(privatePropertyInUnion.ts, 10, 26))
|
||||
>SyncableObject : Symbol(SyncableObject, Decl(privatePropertyInUnion.ts, 2, 28))
|
||||
|
||||
type __ValueDescriptorType<T extends string | object> = T extends ISyncableObject ? SyncableRef<T> : T;
|
||||
>__ValueDescriptorType : Symbol(__ValueDescriptorType, Decl(privatePropertyInUnion.ts, 10, 63))
|
||||
>T : Symbol(T, Decl(privatePropertyInUnion.ts, 12, 27))
|
||||
>T : Symbol(T, Decl(privatePropertyInUnion.ts, 12, 27))
|
||||
>ISyncableObject : Symbol(ISyncableObject, Decl(privatePropertyInUnion.ts, 8, 51))
|
||||
>SyncableRef : Symbol(SyncableRef, Decl(privatePropertyInUnion.ts, 6, 1))
|
||||
>T : Symbol(T, Decl(privatePropertyInUnion.ts, 12, 27))
|
||||
>T : Symbol(T, Decl(privatePropertyInUnion.ts, 12, 27))
|
||||
|
||||
20
tests/baselines/reference/privatePropertyInUnion.types
Normal file
20
tests/baselines/reference/privatePropertyInUnion.types
Normal file
@@ -0,0 +1,20 @@
|
||||
=== tests/cases/compiler/privatePropertyInUnion.ts ===
|
||||
// Repro from #38236
|
||||
|
||||
type Type = string | object;
|
||||
>Type : string | object
|
||||
|
||||
class SyncableObject {
|
||||
>SyncableObject : SyncableObject
|
||||
|
||||
private foo: unknown;
|
||||
>foo : unknown
|
||||
}
|
||||
|
||||
interface SyncableRef<T extends ISyncableObject> {}
|
||||
|
||||
interface ISyncableObject<T = object> extends SyncableObject {}
|
||||
|
||||
type __ValueDescriptorType<T extends string | object> = T extends ISyncableObject ? SyncableRef<T> : T;
|
||||
>__ValueDescriptorType : __ValueDescriptorType<T>
|
||||
|
||||
15
tests/cases/compiler/privatePropertyInUnion.ts
Normal file
15
tests/cases/compiler/privatePropertyInUnion.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
// @strict: true
|
||||
|
||||
// Repro from #38236
|
||||
|
||||
type Type = string | object;
|
||||
|
||||
class SyncableObject {
|
||||
private foo: unknown;
|
||||
}
|
||||
|
||||
interface SyncableRef<T extends ISyncableObject> {}
|
||||
|
||||
interface ISyncableObject<T = object> extends SyncableObject {}
|
||||
|
||||
type __ValueDescriptorType<T extends string | object> = T extends ISyncableObject ? SyncableRef<T> : T;
|
||||
Reference in New Issue
Block a user