Skip to content

Commit b6851ce

Browse files
authored
Emit an interface for a type alias to type literal (#75)
This reduces redundancy. Also, interfaces can be used in bases.
1 parent abf0133 commit b6851ce

File tree

2 files changed

+21
-12
lines changed

2 files changed

+21
-12
lines changed

type-generation/src/astToIR.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1379,10 +1379,24 @@ export class Converter {
13791379
throw new Error("Unhandled");
13801380
case "typeAlias":
13811381
this.nameContext = [name];
1382-
const type = this.typeToIR(classified.decl.getTypeNode()!);
13831382
const aliasTypeParams = classified.decl
13841383
.getTypeParameters()
13851384
.map((p) => p.getName());
1385+
const typeNode = classified.decl.getTypeNode()!;
1386+
// If the typeNode is a type literal, emit an interface instead of a
1387+
// type alias. This reduces redundancy. Also, interfaces can be used in
1388+
// bases.
1389+
if (Node.isTypeLiteral(typeNode)) {
1390+
return this.interfaceToIR(
1391+
name,
1392+
[],
1393+
typeNode.getMembers(),
1394+
[],
1395+
[],
1396+
aliasTypeParams,
1397+
);
1398+
}
1399+
const type = this.typeToIR(typeNode);
13861400
this.nameContext = undefined;
13871401
return { kind: "typeAlias", name, type, typeParams: aliasTypeParams };
13881402
case "varDecl":

type-generation/tests/a.test.ts

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,11 +1395,9 @@ describe("emit", () => {
13951395
assert.strictEqual(
13961396
removeTypeIgnores(res.slice(1).join("\n\n")),
13971397
dedent(`
1398-
type A = A_iface
1399-
14001398
def f() -> A: ...
14011399
1402-
class A_iface(Protocol):
1400+
class A(Protocol):
14031401
a: Literal[1, 2, 3, 4, 5] | None = ...
14041402
b: int | float | None = ...
14051403
c: Literal['a', 'b', 'c'] | None = ...
@@ -1434,16 +1432,15 @@ describe("emit", () => {
14341432
assert.strictEqual(
14351433
removeTypeIgnores(res.slice(1).join("\n\n")),
14361434
dedent(`
1437-
type A = A_iface
1438-
14391435
def f() -> A: ...
14401436
1437+
class A(Protocol):
1438+
a: int | float = ...
1439+
b: A__b_iface = ...
1440+
14411441
class A__b_iface(Protocol):
14421442
c: int | float = ...
14431443
1444-
class A_iface(Protocol):
1445-
a: int | float = ...
1446-
b: A__b_iface = ...
14471444
`).trim(),
14481445
);
14491446
});
@@ -1640,13 +1637,11 @@ describe("emit", () => {
16401637
assert.strictEqual(
16411638
removeTypeIgnores(res.slice(1).join("\n\n")),
16421639
dedent(`
1643-
type A = A_iface
1644-
16451640
type B = A
16461641
16471642
def f(a: A, b: B, /) -> None: ...
16481643
1649-
class A_iface(Protocol):
1644+
class A(Protocol):
16501645
s: bool | None = ...
16511646
t: str | None = ...
16521647
`).trim(),

0 commit comments

Comments
 (0)