Files
scriptc/tests/diagnostics/runtime-optional-refined-union.ts
Chris Tate 06b03f06a9 Compose class references across unions and collections (#734)
* Compose class references across unions and collections

- Compare class, function and native references held in differently represented unions with `===`, `!==` and `Object.is` while preserving subclass identity, and refuse comparisons that a structural union arm leaves undecidable
- Keep subclass values intact through base-typed array and Set insertion spreads, `concat`, and inferred class-predicate `filter`/`find`/`findLast`, and allow checked class refinement of captured optional values with several class arms
- Split the sanitized compiler self-rebuild CI job at the IR boundary, after giving sort helpers distinct IR nodes so serialized and in-memory IR emit the same LLVM

* Keep compact comparisons for plain union arms

- Compare a plain operand with a union that already holds its type through the existing inline union comparison, preserving established parameter representations
- Update the coverage expectation for the accepted class refinement
2026-10-08 07:35:21 -05:00

35 lines
1012 B
TypeScript

// Structural refinements still need a named fence for multi-value storage.
// The class refinement below is accepted through a checked identity-preserving view.
type Item = { rect?: { width: number } };
function hasRect(item: Item | string): item is Item & { rect: { width: number } } {
return typeof item !== "string" && item.rect !== undefined;
}
function recordWidths(items: (Item | string)[]): void {
for (const item of items) {
if (hasRect(item)) console.log(item.rect.width);
}
}
class Animal {
name: string;
constructor(name: string) { this.name = name; }
}
class Dog extends Animal {
bark(): string { return this.name; }
}
function isDog(animal: Animal | string): animal is Dog {
return typeof animal !== "string" && animal instanceof Dog;
}
function classNames(animals: (Animal | string)[]): void {
for (const animal of animals) {
if (isDog(animal)) console.log(animal.bark());
}
}
recordWidths([{ rect: { width: 1 } }, "plain"]);
classNames([new Dog("dog"), "plain"]);