Skip to content
Merged
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
11 changes: 8 additions & 3 deletions src/language/semantics/type-system/type-formats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,15 @@ export type UnionType = {
>
}

export const makeUnionType = (
type SpecificUnionType<Member extends Atom | Exclude<Type, UnionType>> =
UnionType & {
readonly members: ReadonlySet<Member>
}

export const makeUnionType = <Member extends Atom | Exclude<Type, UnionType>>(
name: string,
members: readonly (Atom | Exclude<Type, UnionType>)[],
): UnionType => ({
members: readonly Member[],
): SpecificUnionType<Member> => ({
name,
kind: 'union',
members: new Set(members),
Expand Down
40 changes: 26 additions & 14 deletions src/language/semantics/type-system/type-utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,7 @@ const containedTypeParametersImplementation = (
stringifyKeyPath(root),
{
keyPath: root,
typeParameters:
// TODO: eliminate the type assertion, perhaps by making `makeUnionType` generic
// over the member type
makeUnionType('', [type]) as UnionOfTypeParameters,
typeParameters: makeUnionType('', [type]),
},
],
]),
Expand Down Expand Up @@ -382,18 +379,33 @@ const mergeTypeParametersByKeyPath = (
if (valueFromB === undefined) {
result.set(key, { keyPath, typeParameters })
} else {
// Merge all type(s) at this key path into a union.
// Merge all type(s) at this key path into a (simplified) union.
const supposedTypeParametersAsArray = [
...simplifyUnionType(
makeUnionType(typeParameters.name, [
...typeParameters.members,
...valueFromB.typeParameters.members,
]),
).members.values(),
]
if (
!supposedTypeParametersAsArray.every(
supposedTypeParameter =>
typeof supposedTypeParameter !== 'string' &&
supposedTypeParameter.kind == 'parameter',
)
) {
throw new Error(
'Union type member was unexpectedly not a type parameter. This is a bug!',
)
}

result.set(key, {
keyPath,
typeParameters:
// TODO: eliminate the type assertion, perhaps by making `makeUnionType` and
// `simplifyUnionType` generic over their member types
simplifyUnionType(
makeUnionType(typeParameters.name, [
...typeParameters.members,
...valueFromB.typeParameters.members,
]),
) as UnionOfTypeParameters,
typeParameters: makeUnionType(
typeParameters.name,
supposedTypeParametersAsArray,
),
})
}
}
Expand Down
Loading