Skip to content

@mega-yfue/eufy-sdk / Surface

Type Alias: Surface<M>

ts
type Surface<M> = { readonly [K in keyof M as K extends ValueKeys<M> ? K : never]?: ReadValue<M[K]> } & { [K in keyof M as K extends Exclude<WritableKeys<M>, ConditionalKeys<M>> & string ? SetterName<K, M[K]> : never]: (value: WriteValue<M[K]>) => Promise<void> } & { [K in keyof M as K extends Extract<WritableKeys<M>, ConditionalKeys<M>> & string ? SetterName<K, M[K]> : never]?: (value: WriteValue<M[K]>) => Promise<void> } & { [K in keyof M as K extends Exclude<ActionKeys<M>, ConditionalKeys<M>> & string ? K : never]: () => Promise<void> } & { [K in keyof M as K extends Extract<ActionKeys<M>, ConditionalKeys<M>> & string ? K : never]?: () => Promise<void> } & { [K in keyof M as K extends Exclude<MethodKeys<M>, ConditionalKeys<M>> ? K : never]: M[K] extends MethodMember<infer F> ? F : never } & { [K in keyof M as K extends Extract<MethodKeys<M>, ConditionalKeys<M>> ? K : never]?: M[K] extends MethodMember<infer F> ? F : never } & { [K in keyof M as K extends ProvidedKeys<M> ? K : never]?: M[K] extends { provided: (args: never[]) => infer F } ? Exclude<F, false | undefined> : never };

The bound dev.<cap>() object, derived from the member table.

Getters are optional because they are evidence-gated at runtime — the device may never have reported the param. A write is offered on any device with the capability unless the member gates it.

Every branch maps over keyof M and filters in the as clause rather than over a pre-filtered key union. The two describe the same keys, but only the first is HOMOMORPHIC, and a homomorphic mapped type carries each member's JSDoc through to the projection — so hovering dev.lock().lock() in an editor shows what the member table says about it. Mapping over [K in MethodKeys<M>] silently drops it, which costs the derived surface the one thing a hand-written *Actions type still had over it.

The provider branch matches STRUCTURALLY on the built function rather than on ProvidedMember<P, F>: the provider sits in a contravariant position, so a nominal match against the union's provider type never succeeds. A builder's falsy half is its way of DECLINING, which the optional ? already says, so it is stripped rather than leaking into what a caller holds after the guard.

Type Parameters

M

M extends Members

Independent and unofficial. Not affiliated with, endorsed by, or sponsored by Anker Innovations, Anker eufy, or eufy. "Anker eufy", "eufy" and "Anker" are trademarks of their respective owners. Use responsibly — rapid or failed logins can trigger captcha or temporary cooldowns.