wcb/test/types/typed-props.test-d.ts
Ayo 861310c6bf
Some checks are pending
Tests / Unit (push) Waiting to run
Tests / E2E (push) Waiting to run
feat: typed props
- jsdocs / types change only to enforce giving shapt to `static props`
2026-07-19 18:27:52 +02:00

50 lines
1.4 KiB
TypeScript

/**
* Type-level test for WCB-REQ-02: `this.props.*` is inferred from the shape
* passed as the class type argument. Checked by `pnpm test:types` (tsc only —
* nothing here runs).
*/
import { WebComponent } from '../../dist/index.js'
type Equals<A, B> =
(<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2
? true
: false
type Expect<T extends true> = T
const buttonProps = { variant: 'primary', disabled: false }
class CozyButton extends WebComponent<typeof buttonProps> {
static props = buttonProps
get template() {
// reads are inferred from the defaults, not `any`
type _variantIsString = Expect<Equals<typeof this.props.variant, string>>
type _disabledIsBoolean = Expect<Equals<typeof this.props.disabled, boolean>>
return `<button class="${this.props.variant}"></button>`
}
ok() {
this.props.variant = 'secondary'
this.props.disabled = true
}
wrong() {
// @ts-expect-error string is not assignable to boolean
this.props.disabled = 'x'
// @ts-expect-error boolean is not assignable to string
this.props.variant = false
// @ts-expect-error prop is not declared
this.props.notAProp
}
}
// without a type argument, props stays the permissive PropStringMap
class Untyped extends WebComponent {
static props = { anything: 1 }
read() {
type _isAny = Expect<Equals<typeof this.props.anything, any>>
}
}
export type { CozyButton, Untyped }