widgets/typed_counter/ is the same counter as notebook 1, but the JS module is written in TypeScript and bundled with esbuild — meant as the “copy this when starting a new widget” template for this repo.
The widget surface is identical: value, label, widget_id, three buttons. What’s different sits on disk:
src/index.ts— render function with aCounterModelinterface andRenderProps<CounterModel>from@anywidget/types, somodel.get("value")is typed asnumber.package.json—npm run buildinvokes esbuild, which strips types and emitsdist/widget.js.npm run typecheckrunstsc --noEmitfor type-only checks.tsconfig.json— strict, ES2020,moduleResolution: bundler.widget.py— sameanywidget.AnyWidgetsubclass pattern, with_esmpointing at the built bundle indist/.
Nothing in the static-export plugin or the runtime knows or cares that the source was TypeScript — by the time the widget reaches the browser it’s plain ESM JavaScript.
import sys
import pathlib
sys.path.insert(0, str(pathlib.Path().absolute().parent))
from widgets.typed_counter import TypedCounterWidgetConstruct one and display it:
TypedCounterWidget(label="Typed counter", widget_id="ts_counter_demo", value=3)Two on the same page work the same way as the JS counter — independent state, no shared globals:
TypedCounterWidget(label="Another one", widget_id="ts_counter_demo_2", value=10)