Skip to content

Commit

Permalink
fix: remove rec. type from cache after check
Browse files Browse the repository at this point in the history
The intersection case for interfaces and partials contained a bug where recursive types gave false positives
  • Loading branch information
pieterjanv committed Apr 22, 2024
1 parent 8cd382c commit 50c03a8
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 20 deletions.
4 changes: 0 additions & 4 deletions src/extensionRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,10 @@ type SetPropsSourceResult = (

export type HasExtendingProp = (
source: t.Type<unknown>,
targetKey: string | number,
targetType: t.Type<unknown>,
) => Ternary;

export type HasPartiallyExtendingProp = (
source: t.Type<unknown>,
targetKey: string | number,
targetType: t.Type<unknown>,
) => Ternary | undefined;

type DictionaryIntersectionHandler<S extends TypeCtor, T extends TypeCtor> = (
Expand Down
4 changes: 2 additions & 2 deletions src/types/clss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ export function initClss() {
targetType,
isExtendedBy,
hasExtendingProp,
) => hasExtendingProp(source.type, targetKey, targetType),
) => hasExtendingProp(source.type),
);

extensionRegistry.register<
Expand All @@ -254,7 +254,7 @@ export function initClss() {
targetType,
isExtendedBy,
hasPartiallyExtendingProp,
) => hasPartiallyExtendingProp(source.type, targetKey, targetType),
) => hasPartiallyExtendingProp(source.type),
);

extensionRegistry.register(
Expand Down
23 changes: 13 additions & 10 deletions src/types/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export function initInterface() {
targetType,
isExtendedBy,
hasExtendingProp,
) => hasExtendingProp(source.type, targetKey, targetType),
) => hasExtendingProp(source.type),
);

extensionRegistry.register(
Expand Down Expand Up @@ -185,21 +185,24 @@ export function initInterface() {
return Ternary.Maybe;
}
expanded.push(source);
const SourceMemberCtor = Object.getPrototypeOf(source).constructor as TypeCtor;
const handler = extensionRegistry.getInterfaceIntersectionHandler(SourceMemberCtor);
const SourceCtor = Object.getPrototypeOf(source).constructor as TypeCtor;
const handler = extensionRegistry.getInterfaceIntersectionHandler(SourceCtor);
let result: Ternary = Ternary.False;
handler && (result = handler(
source,
targetKey,
targetType,
isExtendedBy,
(source, targetKey, targetType) => hasExtendingProp(
source,
(s) => hasExtendingProp(
s,
targetKey,
targetType,
expanded,
),
));

expanded.pop();

return result;
}
},
Expand All @@ -211,7 +214,7 @@ export function initInterface() {
hasExtendingProp,
) => ternarySome(
source.types as t.Type<unknown>[],
(source) => hasExtendingProp(source, targetKey, targetType),
(s) => hasExtendingProp(s),
),
);

Expand All @@ -227,7 +230,7 @@ export function initInterface() {
hasExtendingProp,
) => ternaryEvery(
source.types as t.Type<unknown>[],
(sourceType) => hasExtendingProp(sourceType, targetKey, targetType)
(sourceType) => hasExtendingProp(sourceType)
),
);

Expand All @@ -245,7 +248,7 @@ export function initInterface() {
targetType,
isExtendedBy,
hasExtendingProp,
) => hasExtendingProp(source.type, targetKey, targetType),
) => hasExtendingProp(source.type),
);

extensionRegistry.register(
Expand All @@ -262,7 +265,7 @@ export function initInterface() {
targetType,
isExtendedBy,
hasExtendingProp,
) => hasExtendingProp(source.type, targetKey, targetType),
) => hasExtendingProp(source.type),
);

extensionRegistry.register(
Expand All @@ -279,6 +282,6 @@ export function initInterface() {
targetType,
isExtendedBy,
hasExtendingProp,
) => hasExtendingProp(source.type, targetKey, targetType),
) => hasExtendingProp(source.type),
);
}
11 changes: 7 additions & 4 deletions src/types/partial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,16 @@ export function initPartial() {
targetKey,
targetType,
isExtendedBy,
(source, targetKey, targetType) => hasPartiallyExtendingProp(
(source) => hasPartiallyExtendingProp(
source,
targetKey,
targetType,
expanded,
),
));

expanded.pop();

return result;
}
},
Expand All @@ -127,7 +130,7 @@ export function initPartial() {
) => {
let result: Ternary | undefined = undefined;
for (const type of source.types) {
const r = hasPartiallyExtendingProp(type, targetKey, targetType);
const r = hasPartiallyExtendingProp(type);
switch(r) {
case Ternary.True:
return Ternary.True;
Expand Down Expand Up @@ -155,7 +158,7 @@ export function initPartial() {
) => {
let result: Ternary | undefined = undefined;
for (const type of source.types) {
const r = hasPartiallyExtendingProp(type, targetKey, targetType);
const r = hasPartiallyExtendingProp(type);
switch(r) {
case Ternary.False:
return Ternary.False;
Expand Down Expand Up @@ -229,7 +232,7 @@ export function initPartial() {
isExtendedBy: IsExtendedBy,
hasPartiallyExtendingProp: HasPartiallyExtendingProp,
) {
return hasPartiallyExtendingProp(source.type, targetKey, targetType);
return hasPartiallyExtendingProp(source.type);
}

function interfaceOrPartialSourceHandler<
Expand Down
10 changes: 10 additions & 0 deletions test/by-type/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ export default [
(t.type(helpers.emptyProps)),
true,
],
[
t.record(t.string, t.string),
t.type({ a: t.number }),
false,
],
[
t.exact(t.type({ a: t.string })),
t.type({ a: t.string }),
Expand Down Expand Up @@ -147,6 +152,11 @@ export default [
(t.type({ a: t.string })),
true,
],
[
helpers.v1,
(t.type({ a: t.number })),
false,
],
[
t.brand(t.type({a: t.string}), (x): x is t.Branded<{a: string}, helpers.Brand> => true, 'Brand'),
(t.type({ a: t.string })),
Expand Down

0 comments on commit 50c03a8

Please sign in to comment.