Closed sunnyrjuneja closed 6 years ago
According to https://discourse.stimulusjs.org/t/syntax-error-when-using-targets/23/8 this is not (yet?) possible, instead you’d have to declare each target explicitly.
Thank you @docstun! I see that someone has the same problem as me. I should have checked the forum too :). Since the maintainers are aware of the issue and there is a workaround, I'll close this issue.
Workaround for future searchers:
import { Controller } from "stimulus"
export default class extends Controller {
nameTarget: Element
nameTargets: Element[]
hasNameTarget: boolean
static targets = [ "name" ]
// …
}
I'm not sure how easy/hard this would be to do, but it looks like a similar problem to defaultProps
for JSX. That was just added in TS 3.0.
FYI:
If you use @sunnyrjuneja 's sulotion, you will need this config in tsconfig file, otherwise it will raise an error: xxxx has no initializer and is not definitely assigned in the constructor.
"strictPropertyInitialization":false
@NaiveCAI This is my tsconfig:
{
"compilerOptions": {
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es6", "dom"],
"module": "es6",
"moduleResolution": "node",
"sourceMap": true,
"target": "es5"
},
"exclude": [
"**/*.spec.ts",
"node_modules",
"vendor",
"public"
],
"compileOnSave": false
}
FYI:
If you use @sunnyrjuneja 's sulotion, you will need this config in tsconfig file, otherwise it will raise an error:
xxxx has no initializer and is not definitely assigned in the constructor.
"strictPropertyInitialization":false
You can use an exclamation point to bypass the strict initialization check:
class extends Controller {
static targets = [ "name" ]
readonly nameTarget!: Element
readonly nameTargets!: Element[]
readonly hasNameTargets!: boolean
}
I've been trying to use the approach listed here but I've come across an issue.
Using syntax such as
class extends Controller {
static targets = [ "name" ]
readonly nameTarget!: Element
readonly nameTargets!: Element[]
readonly hasNameTargets!: boolean
}
This gets compiled down to:
_this.nameTarget = void 0;
_this.nameTargets = void 0;
_this.hasNameTarget = void 0;
And an error appears in the console:
TypeError: Cannot set property nameTarget of #<Controller> which has only a getter
Pausing the debugger at this point, inspecting this.nameTarget
reveals that it has already been set to the correct DOM element, and stimulus is (correctly) stopping any assignment to this value.
I wonder if there is a way to tell TypeScript that we have a nameTarget
property without compiling this into code that tries to initialise the property? (I do wonder if this is a babel issue rather than TypeScript though).
EDIT: on further investigation it appears that this is the behaviour of the @babel/plugin-proposal-class-properties
plugin, if you do not initialise the property then it will compile down to initialise with void 0
. I guess I need to find another way to make TypeScript happy 😄
Related: https://github.com/babel/babel/issues/7644
I'll open a new issue.
Hi there!
Thanks for open sourcing stimulus. It's been a real joy to use so far and I'm excited to really dig deep into it.
I noticed that the default example creates a typescript compiler error.
The Stimulus documentation says:
Is there anyway to let Typescript know about this.sourceTarget, this.sourceTargets, and this.hasSourceTarget? I thought this might be alleviate since the library is written in Typescript.