Skip to content

Commit 029cc2e

Browse files
committed
setting up another stable decorators experiment
1 parent be20bd3 commit 029cc2e

File tree

7 files changed

+109
-15
lines changed

7 files changed

+109
-15
lines changed

babel.config.mjs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ export default {
1717
allowDeclareFields: true,
1818
},
1919
],
20-
[
21-
'module:decorator-transforms',
22-
{
23-
runEarly: true,
24-
runtime: { import: 'decorator-transforms/runtime' },
25-
},
26-
],
20+
['@babel/plugin-proposal-decorators', { version: '2023-11' }],
21+
// [
22+
// 'module:decorator-transforms',
23+
// {
24+
// runEarly: true,
25+
// runtime: { import: 'decorator-transforms/runtime' },
26+
// },
27+
// ],
2728
[
2829
'babel-plugin-ember-template-compilation',
2930
{

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@
107107
},
108108
"devDependencies": {
109109
"@aws-sdk/client-s3": "^3.731.0",
110-
"@babel/plugin-transform-typescript": "^7.22.9",
110+
"@babel/plugin-proposal-decorators": "^7.25.9",
111+
"@babel/plugin-transform-typescript": "^7.26.8",
111112
"@babel/preset-env": "^7.16.11",
112113
"@babel/types": "^7.22.5",
113114
"@embroider/shared-internals": "^2.5.0",
@@ -400,4 +401,4 @@
400401
}
401402
},
402403
"packageManager": "[email protected]"
403-
}
404+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
Types and utilities for working with 2023-11 decorators -- the ones that are
3+
currently (as of 2025-05-05) in Stage 3.
4+
5+
TypeScript provides built-in types for all the Context objects, but not a way
6+
to do type discrimination against the `value` argument.
7+
*/
8+
9+
export type ClassMethodDecorator = (
10+
value: Function,
11+
context: ClassMethodDecoratorContext
12+
) => Function | void;
13+
14+
export type ClassGetterDecorator = (
15+
value: Function,
16+
context: ClassGetterDecoratorContext
17+
) => Function | void;
18+
19+
export type ClassSetterDecorator = (
20+
value: Function,
21+
context: ClassSetterDecoratorContext
22+
) => Function | void;
23+
24+
export type ClassFieldDecorator = (
25+
value: undefined,
26+
context: ClassFieldDecoratorContext
27+
) => (initialValue: unknown) => unknown | void;
28+
29+
export type ClassDecorator = (value: Function, context: ClassDecoratorContext) => Function | void;
30+
31+
export type ClassAutoAccessorDecorator = (
32+
value: ClassAccessorDecoratorTarget<unknown, unknown>,
33+
context: ClassAccessorDecoratorContext
34+
) => ClassAccessorDecoratorResult<unknown, unknown>;
35+
36+
export type Decorator =
37+
| ClassMethodDecorator
38+
| ClassGetterDecorator
39+
| ClassSetterDecorator
40+
| ClassFieldDecorator
41+
| ClassDecorator
42+
| ClassAutoAccessorDecorator;
43+
44+
export function isModernDecoratorArgs(args: unknown[]): args is Parameters<Decorator> {
45+
return args.length === 2 && typeof args[1] === 'object' && args[1] != null && 'kind' in args[1];
46+
}
47+
48+
// this is designed to turn the arguments into a discriminated union so you can
49+
// check the kind once and then have the right types for them.
50+
export function identifyModernDecoratorArgs(args: Parameters<Decorator>):
51+
| {
52+
kind: 'method';
53+
value: Parameters<ClassMethodDecorator>[0];
54+
context: Parameters<ClassMethodDecorator>[1];
55+
}
56+
| {
57+
kind: 'getter';
58+
value: Parameters<ClassGetterDecorator>[0];
59+
context: Parameters<ClassGetterDecorator>[1];
60+
}
61+
| {
62+
kind: 'setter';
63+
value: Parameters<ClassSetterDecorator>[0];
64+
context: Parameters<ClassSetterDecorator>[1];
65+
}
66+
| {
67+
kind: 'field';
68+
value: Parameters<ClassFieldDecorator>[0];
69+
context: Parameters<ClassFieldDecorator>[1];
70+
}
71+
| {
72+
kind: 'class';
73+
value: Parameters<ClassDecorator>[0];
74+
context: Parameters<ClassDecorator>[1];
75+
}
76+
| {
77+
kind: 'accessor';
78+
value: Parameters<ClassAutoAccessorDecorator>[0];
79+
context: Parameters<ClassAutoAccessorDecorator>[1];
80+
} {
81+
return {
82+
kind: args[1].kind,
83+
value: args[0],
84+
context: args[1],
85+
} as ReturnType<typeof identifyModernDecoratorArgs>;
86+
}

pnpm-lock.yaml

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rollup.config.mjs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,10 +247,10 @@ export function hiddenDependencies() {
247247
'module'
248248
).path,
249249
...walkGlimmerDeps(['@glimmer/compiler']),
250-
'decorator-transforms/runtime': resolve(
251-
findFromProject('decorator-transforms').root,
252-
'dist/runtime.js'
253-
),
250+
// 'decorator-transforms/runtime': resolve(
251+
// findFromProject('decorator-transforms').root,
252+
// 'dist/runtime.js'
253+
// ),
254254
};
255255
}
256256

tsconfig/compiler-options.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
"rootDir": "../packages",
1010

1111
// Environment Configuration
12-
"experimentalDecorators": true,
1312
"moduleResolution": "bundler",
1413

1514
// Enhance Strictness

vite.config.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ export default defineConfig(({ mode }) => {
4343
optimizeDeps: { noDiscovery: true },
4444
publicDir: 'tests/public',
4545
build,
46+
47+
// the stock esbuild support for typescript is horribly broken. For example,
48+
// it will simply remove your decorators.
49+
esbuild: false,
4650
};
4751
});
4852

0 commit comments

Comments
 (0)