Skip to content

Commit ad9a492

Browse files
authored
chore: improve member expression computed typechecking (#5157)
1 parent a88ebeb commit ad9a492

File tree

1 file changed

+38
-31
lines changed
  • packages/@lwc/babel-plugin-component/src/decorators/wire

1 file changed

+38
-31
lines changed

packages/@lwc/babel-plugin-component/src/decorators/wire/validate.ts

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -25,60 +25,67 @@ function validateWireId(id: NodePath | undefined, path: NodePath, state: LwcBabe
2525
);
2626
}
2727

28-
const isMemberExpression = id.isMemberExpression();
28+
let adapter: NodePath<types.Identifier>;
2929

30-
if (!id.isIdentifier() && !isMemberExpression) {
31-
throw generateError(
32-
id,
33-
{
34-
errorInfo: DecoratorErrors.FUNCTION_IDENTIFIER_SHOULD_BE_FIRST_PARAMETER,
35-
},
36-
state
37-
);
38-
}
30+
if (id.isIdentifier()) {
31+
// @wire(adapter)
32+
adapter = id;
33+
} else if (id.isMemberExpression()) {
34+
if (id.node.computed) {
35+
// @wire(adapter[computed])
36+
throw generateError(
37+
id,
38+
{
39+
errorInfo: DecoratorErrors.FUNCTION_IDENTIFIER_CANNOT_HAVE_COMPUTED_PROPS,
40+
},
41+
state
42+
);
43+
}
3944

40-
if (id.isMemberExpression({ computed: true })) {
41-
throw generateError(
42-
id,
43-
{
44-
errorInfo: DecoratorErrors.FUNCTION_IDENTIFIER_CANNOT_HAVE_COMPUTED_PROPS,
45-
},
46-
state
47-
);
48-
}
45+
const object = id.get('object');
4946

50-
// TODO [#3444]: improve member expression computed typechecking
51-
// @ts-expect-error type narrowing incorrectly reduces id to `never`
52-
if (isMemberExpression && !id.get('object').isIdentifier()) {
47+
if (object.isIdentifier()) {
48+
// @wire(adapter.foo)
49+
adapter = object;
50+
} else {
51+
// @wire(adapter.foo.bar)
52+
throw generateError(
53+
id,
54+
{
55+
errorInfo:
56+
DecoratorErrors.FUNCTION_IDENTIFIER_CANNOT_HAVE_NESTED_MEMBER_EXRESSIONS,
57+
},
58+
state
59+
);
60+
}
61+
} else {
62+
// @wire(1), @wire('adapter'), @wire(function adapter() {}), etc.
5363
throw generateError(
5464
id,
5565
{
56-
errorInfo: DecoratorErrors.FUNCTION_IDENTIFIER_CANNOT_HAVE_NESTED_MEMBER_EXRESSIONS,
66+
errorInfo: DecoratorErrors.FUNCTION_IDENTIFIER_SHOULD_BE_FIRST_PARAMETER,
5767
},
5868
state
5969
);
6070
}
6171

62-
// TODO [#3444]: improve member expression computed typechecking
6372
// Ensure wire adapter is imported (check for member expression or identifier)
64-
// @ts-expect-error type narrowing incorrectly reduces id to `never`
65-
const wireBinding = isMemberExpression ? id.node.object.name : id.node.name;
66-
if (!path.scope.getBinding(wireBinding)) {
73+
const adapterBinding = path.scope.getBinding(adapter.node.name);
74+
if (!adapterBinding) {
6775
throw generateError(
6876
id,
6977
{
7078
errorInfo: DecoratorErrors.WIRE_ADAPTER_SHOULD_BE_IMPORTED,
71-
messageArgs: [id.node.name],
79+
messageArgs: [adapter.node.name],
7280
},
7381
state
7482
);
7583
}
7684

7785
// ensure wire adapter is a first parameter
7886
if (
79-
wireBinding &&
80-
!path.scope.getBinding(wireBinding)!.path.isImportSpecifier() &&
81-
!path.scope.getBinding(wireBinding)!.path.isImportDefaultSpecifier()
87+
!adapterBinding.path.isImportSpecifier() &&
88+
!adapterBinding.path.isImportDefaultSpecifier()
8289
) {
8390
throw generateError(
8491
id,

0 commit comments

Comments
 (0)