Skip to content

Commit f9fa0c9

Browse files
authored
Handle type literals in interfaces (#69)
1 parent b6c4aef commit f9fa0c9

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

type-generation/src/astToIR.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,19 @@ class SyntheticTypeConverter {
402402
switch (typeRoot.kind) {
403403
case "intersection": {
404404
const node = typeRoot.node;
405+
for (const ty of node.getTypeNodes()) {
406+
if (ty.getType().isTypeParameter()) {
407+
// Can't intersect with a type parameter...
408+
return ANY_IR;
409+
}
410+
if (
411+
Node.isTypeReference(ty) &&
412+
Node.isQualifiedName(ty.getTypeName())
413+
) {
414+
// We don't handle QualifiedNames yet
415+
return ANY_IR;
416+
}
417+
}
405418
const types = node
406419
.getTypeNodes()
407420
.map((ty, idx) => {
@@ -424,6 +437,11 @@ class SyntheticTypeConverter {
424437
return res;
425438
})
426439
.filter((x): x is ReferenceTypeIR => !!x && x.kind === "reference");
440+
for (const node of types) {
441+
if (!node.name.endsWith("_iface")) {
442+
node.name += "_iface";
443+
}
444+
}
427445
const name = this.nameContext.join("__") + "_iface";
428446
this.converter.extraTopLevels.push(
429447
this.converter.interfaceToIR(name, types, [], [], [], []),
@@ -1453,6 +1471,7 @@ export function convertDecls(
14531471
.getBasesOfDecls(defs)
14541472
.filter((base) => base.name !== name);
14551473
const typeParams = converter.getTypeParamsFromDecls(defs);
1474+
converter.nameContext = [name];
14561475
const res = converter.interfaceToIR(
14571476
name,
14581477
baseNames,
@@ -1461,6 +1480,7 @@ export function convertDecls(
14611480
defs.flatMap((def) => def.getCallSignatures()),
14621481
typeParams,
14631482
);
1483+
converter.nameContext = undefined;
14641484
pushTopLevel(res);
14651485

14661486
// Clear interface type parameter constraints after processing interface

type-generation/tests/a.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,6 +1882,26 @@ describe("emit", () => {
18821882
`).trim(),
18831883
);
18841884
});
1885+
it("type literal in interface", () => {
1886+
const res = emitFile(`
1887+
interface O {
1888+
x?: { a: string; };
1889+
};
1890+
declare function f(): O<string>;
1891+
`);
1892+
assert.strictEqual(
1893+
removeTypeIgnores(res.slice(1).join("\n\n")),
1894+
dedent(`
1895+
def f() -> O_iface[str]: ...
1896+
1897+
class O_iface(Protocol):
1898+
x: O_iface__x_iface | None = ...
1899+
1900+
class O_iface__x_iface(Protocol):
1901+
a: str = ...
1902+
`).trim(),
1903+
);
1904+
});
18851905
});
18861906
describe("adjustments", () => {
18871907
it("setTimeout", () => {

0 commit comments

Comments
 (0)