Skip to content

Conversation

JohannesMeierSE
Copy link
Collaborator

@JohannesMeierSE JohannesMeierSE commented Sep 4, 2025

This PR improves the handling of optional properties for custom types:

  • It fixes a bug reported in #77 when assigning undefined in explicit way to optional properties.
  • It fixes another bug when comparing optional custom properties for equality.
  • It enables to define properties for custom types using undefined in explicit way.

@JohannesMeierSE JohannesMeierSE added this to the v0.4 milestone Sep 4, 2025
# Conflicts:
#	CHANGELOG.md
#	packages/typir/src/kinds/custom/custom-type.ts
Copy link
Member

@insafuhrmann insafuhrmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for these fixes @JohannesMeierSE. I am going to approve but I'd like to understand the topic in my detail remark.

### Fixed bugs

- Initializing optional properties of custom types with `undefined` failed, as reported in [#77](https://github.com/TypeFox/typir/discussions/77#discussioncomment-14149139).
- When checking the equality of custom types, the values for the same property might have different TypeScript types, since optional propeties might be set to `undefined`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- When checking the equality of custom types, the values for the same property might have different TypeScript types, since optional propeties might be set to `undefined`.
- When checking the equality of custom types, the values for the same property might have different TypeScript types, since optional properties might be set to `undefined`.

protected analyzeTypeEqualityProblemsSingle<T extends CustomTypePropertyTypes>(value1: CustomTypePropertyStorage<T, Specifics>, value2: CustomTypePropertyStorage<T, Specifics>): TypirProblem[] {
assertTrue(typeof value1 === typeof value2);
if (typeof value1 !== typeof value2) {
// this case might occur for optional properties, since `undefined` is a different TypeScript type than a non-undefined value
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get that this case exists now, but I am not sure I understand why it should raise a ValueConflict.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the problem is that I do not really have the concrete bug you wish to solve in mind. I am thinking for an optional property, why should undefined not be treated as if it were equal to an actual value, or put in a different way, should it not be treated as if it were of the same type as the value (though it technically isn't)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The critical case is, when I have two custom types with the same properties, but different values for them, e.g. MyCustom1 { optionalProperty: 'hello' } and MyCustom2 { optionalProperty: undefined }. These two custom types are not equal, since they have different values for the optionalProperty property.

Since 'hello' and undefined have different TypeScript types (string vs undefined), the new line 172 detects a difference here and reports a problem.

Maybe we should not report the different TypeScript types, but the different values?

return [<ValueConflict>{
    $problem: ValueConflict,
    firstValue: String(value1),
    secondValue: String(value2),
}];

Line 172 is also important in order to cast values (e.g. line 182) or assert TypeScript types (e.g. line 186) later on.

Do these explanations answers your questions?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants