-
Notifications
You must be signed in to change notification settings - Fork 709
fix(1685): refine export assignment diagnostics to match strada #1688
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
...data/baselines/reference/submodule/conformance/jsDeclarationsFunctionPrototypeStatic.js.diff
Show resolved
Hide resolved
@sandersn @weswigham Is this the thing we were discussing about relaxing this for even TS code and not erroring at all? I can't remember where we left that. |
We're at the "just do it like strada" stage because trying to improve it just moved where the jank in our code is - better the jank we know. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely an improvement. I'm sure we'll have to keep adjusting the JS declaration emit for export assignments, though, since they're still only partially supported.
|
||
|
||
==== out/source.d.ts (2 errors) ==== | ||
export = MyClass; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm. This is because we don't actually support constructor functions yet, right @sandersn ?
-export type SomeType = { | ||
+type SomeType = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one is regressing; maybe a bad interplay with the new code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is somewhat of a regression, related to how Corsa handles the module.exports = {}
export assignment, for instance
/**
* @typedef {{x: string} | number | LocalThing | ExportedThing} SomeType
*/
/**
* @param {number} x
* @returns {SomeType}
*/
function doTheThing(x) {
return {x: ""+x};
}
class ExportedThing {
z = "ok"
}
module.exports = {
doTheThing,
ExportedThing,
};
class LocalThing {
y = "ok"
}
Strada
export type SomeType = {
x: string;
} | number | LocalThing | ExportedThing;
/**
* @typedef {{x: string} | number | LocalThing | ExportedThing} SomeType
*/
/**
* @param {number} x
* @returns {SomeType}
*/
declare function doTheThing(x: number): SomeType;
declare class ExportedThing {
z: string;
}
declare class LocalThing {
y: string;
}
export {};
Corsa
//// [mixed.d.ts]
type SomeType = {
x: string;
} | number | LocalThing | ExportedThing;
/**
* @typedef {{x: string} | number | LocalThing | ExportedThing} SomeType
*/
/**
* @param {number} x
* @returns {SomeType}
*/
declare function doTheThing(x: number): SomeType;
declare class ExportedThing {
z: string;
}
declare const _default: {
doTheThing: typeof doTheThing;
ExportedThing: typeof ExportedThing;
};
export = _default;
declare class LocalThing {
y: string;
}
typescript-go/internal/transformers/declarations/transform.go
Lines 916 to 939 in 0522ac5
newId := tx.Factory().NewUniqueNameEx("_default", printer.AutoGenerateOptions{Flags: printer.GeneratedIdentifierFlagsOptimistic}) | |
tx.state.getSymbolAccessibilityDiagnostic = func(_ printer.SymbolAccessibilityResult) *SymbolAccessibilityDiagnostic { | |
return &SymbolAccessibilityDiagnostic{ | |
diagnosticMessage: diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0, | |
errorNode: input, | |
} | |
} | |
tx.tracker.PushErrorFallbackNode(input) | |
type_ := tx.ensureType(input, false) | |
varDecl := tx.Factory().NewVariableDeclaration(newId, nil, type_, nil) | |
tx.tracker.PopErrorFallbackNode() | |
var modList *ast.ModifierList | |
if tx.needsDeclare { | |
modList = tx.Factory().NewModifierList([]*ast.Node{tx.Factory().NewModifier(ast.KindDeclareKeyword)}) | |
} else { | |
modList = tx.Factory().NewModifierList([]*ast.Node{}) | |
} | |
statement := tx.Factory().NewVariableStatement(modList, tx.Factory().NewVariableDeclarationList(ast.NodeFlagsConst, tx.Factory().NewNodeList([]*ast.Node{varDecl}))) | |
assignment := tx.Factory().UpdateExportAssignment(input.AsExportAssignment(), input.Modifiers(), input.Type(), newId) | |
// Remove comments from the export declaration and copy them onto the synthetic _default declaration | |
tx.preserveJsDoc(statement, input) | |
tx.removeAllComments(assignment) | |
return tx.Factory().NewSyntaxList([]*ast.Node{statement, assignment}) |
Since export = _default;
is present, all other exports should be elided to avoid mismatches related to this error handling.
I think fixing this regression requires changing how export assignments are handled, so cases like
module.exports = {
doTheThing,
ExportedThing,
};
are transformed without emitting them as a default export. @jakebailey WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds about right, I think? (Not personally an expert in this crossover)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@weswigham @jakebailey I’m wondering if, instead of replicating Strada’s JavaScript declaration emitter, which produces
// @input: a.js
/**
* @typedef {string | number} T
*/
class A { }
module.exports = {
A,
}
// @output: a.d.ts
export type T = string | number;
/**
* @typedef {string | number} T
*/
export class A {
}
it might make more sense to align more closely with what TypeScript’s transformer does, and adjust the output to something like this...
// @output: a.d.ts
declare class A {}
declare const _default: {
A: typeof A;
};
export = _default;
declare namespace _default {
type T = string | number;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't the impact of that be that A
is inaccessible from type space?
-export type Conn = import("./conn"); | ||
+type Conn = import("./conn"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one too? (I hate JSDoc typedef rules)
-export type TaskGroupIds = "parseHTML" | "styleLayout"; | ||
+export type TaskGroupIds = 'parseHTML' | 'styleLayout'; | ||
export type TaskGroup = { | ||
-export type TaskGroup = { | ||
+type TaskGroupIds = 'parseHTML' | 'styleLayout'; | ||
+type TaskGroup = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file's also regressing in a similar way, it seems...
Fixes #1685
This patch addresses the issue of incomplete export assignment validation by aligning the check with
Strada
logic.