Last active
February 9, 2021 09:37
-
-
Save pushkine/d2ebc3e7131f7a658e5ca7bdf0150574 to your computer and use it in GitHub Desktop.
Accurate typings for Svelte's compiler output, includes comments for ambiguous properties and type functions for advanced use cases
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface LifecycleFunction { | |
(): void; | |
} | |
interface EventCallback<T = unknown> { | |
(event: CustomEvent<T>): void; | |
} | |
export namespace Svelte { | |
export interface Fragment { | |
key?: string | null; | |
first?: Comment | null; | |
c(): void; | |
l?(nodes: any): void; | |
h?(): void; | |
m(target: HTMLElement, anchor: HTMLElement): void; | |
p(ctx: ctx, dirty: dirtyUpdate): void; | |
r?(): void; | |
f?(): void; | |
a?(): void; | |
i?(local: 0 | 1 | boolean): void; | |
o?(local: 0 | 1 | boolean): void; | |
d(detaching: 0 | 1 | boolean): void; | |
} | |
export interface CreateFragment { | |
(ctx: ctx): Svelte.Fragment; | |
} | |
export type ctx = any[]; | |
export type dirty = number[]; | |
export type dirtyUpdate = number | dirty; | |
export type scopeInit = { readonly ctx: ctx }; | |
export type scopeUpdate = { readonly ctx: ctx; readonly dirty: dirtyUpdate }; | |
export namespace Slot { | |
export interface Init { | |
$$slots: { | |
default?: Template; | |
[name: string]: Template; | |
}; | |
$$scope: { | |
ctx: ctx; | |
}; | |
} | |
export interface Update { | |
$$scope?: { | |
ctx: ctx; | |
dirty: dirtyUpdate; | |
}; | |
} | |
export interface UpdateLetCtx { | |
(ctx_lets: { [let_name: string]: unknown }): { [lets_index_in_ctx: number]: unknown }; | |
} | |
export interface DirtyLet { | |
(dirty_lets: { [let_name: string]: boolean }): dirtyUpdate; | |
} | |
export type Template = [CreateFragment] | [CreateFragment, UpdateLetCtx, DirtyLet]; | |
} | |
type Props = { [prop_name: string]: any }; | |
type Events = { [event_name: string]: any }; | |
type Slots = { [slot_name: string]: { [let_name: string]: any } } | {}; | |
export namespace Component { | |
export interface Instance<P extends Props = {}, E extends Events = {}, S extends Slots = {}> { | |
readonly __proto__?: { readonly constructor: Constructor<P, E, S> }; | |
$$prop_def: P; // svelte extension only | |
$$events_def: E; // svelte extension only | |
$$slot_def: S; // svelte extension only | |
$$: T$$; | |
$$set?: ($$props: Partial<P> & Slot.Update) => void; | |
$set(props: Partial<P> & Slot.Update): void; | |
$on<K extends keyof E & string>(event: K, handler: (e: CustomEvent<E[K]>) => void): () => void; | |
$destroy(): void; | |
$capture_state?(): void; | |
$inject_state?(): void; | |
} | |
export interface T$$ { | |
fragment: Svelte.Fragment; // fragment | false (no markup) | null (destroyed) | |
update: () => void; // updates reactive statements | |
dirty: dirty; | |
ctx: ctx; | |
bound: Record<number, (value: unknown) => void>; // prop index in ctx -> bind callback | |
skip_bound: boolean; // prevents upstream bindings callbacks when props flow downstream | |
callbacks: { [event_name: string]: EventCallback[] }; // event listener callbacks | |
props: { [prop_name: string]: number }; // index in ctx | |
not_equal: (a: any, b: any) => boolean; | |
context: Map<any, any>; | |
on_mount: LifecycleFunction[]; | |
on_destroy: LifecycleFunction[]; | |
before_update: LifecycleFunction[]; | |
after_update: LifecycleFunction[]; | |
} | |
export interface StandaloneOptions<P extends Props = {}> { | |
props?: P; | |
target: HTMLElement; | |
anchor?: HTMLElement; | |
hydrate?: boolean; | |
intro?: boolean; | |
} | |
export interface CompiledOptions<P extends Props = {}> { | |
props?: Slot.Init & Omit<P, keyof Slot.Init>; | |
$$inline?: boolean; // avoids "no target" dev-mode warning when using CompiledOptions | |
} | |
export type Options<P extends Props = {}> = StandaloneOptions<P> | CompiledOptions<P> | {}; | |
export interface Constructor<P extends Props = {}, E extends Events = {}, S extends Slots = {}> { | |
new (options: Options<P>): Instance<P, E, S>; | |
} | |
} | |
type ExtractDef<T, K extends string> = (T extends new (...args: any[]) => infer U ? U : T) extends { | |
[_ in `$$${K}_def`]: infer U; | |
} | |
? U | |
: never; | |
type Spread<T, U> = { [K in keyof T | keyof U]: K & keyof U extends never ? T[K & keyof T] : U[K & keyof U] }; | |
export type PropsOf<T> = ExtractDef<T, "prop">; | |
export type EventsOf<T> = ExtractDef<T, "events">; | |
export type SlotsOf<T> = ExtractDef<T, "slot">; | |
export type OptionsOf<T> = Component.Options<PropsOf<T>>; | |
export type ConstructorOf<T> = Component.Constructor<PropsOf<T>, EventsOf<T>, SlotsOf<T>>; | |
export type InstanceOf<T> = Component.Instance<PropsOf<T>, EventsOf<T>, SlotsOf<T>>; | |
export type PropKeyOf<T> = keyof PropsOf<T> & string; | |
export type PropValueOf<T, K extends PropKeyOf<T> = PropKeyOf<T>> = PropsOf<T>[K]; | |
export type SpreadProps<A, B> = Spread<PropsOf<A>, PropsOf<B>>; | |
export type SpreadEvents<A, B> = Spread<EventsOf<A>, EventsOf<B>>; | |
export type SpreadSlots<A, B> = Spread<SlotsOf<A>, SlotsOf<B>>; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment