I was writing a wrapper for creating SVG filter elements before I realized that I should just use the HTML elements instead (in Svelte that is).
I did learn something though, when you want to type something where the available parameters change depending on something (in my case a light type) you can use typescript generics and indexed access types.
Some light types:
export type LightTypes = {
feDistantLight: FeDistantLightAttributes;
fePointLight: FePointLightAttributes;
feSpotLight: FeSpotLightAttributes;
};
Some example attributes:
export type FeDiffuseLightingAttributes = {
in?: inType;
diffuseConstant?: number;
surfaceScale?: number;
"lighting-color"?: string;
result?: string;
};
export type FeDistantLightAttributes = {
azimuth?: number;
elevation?: number;
};
The function:
feDiffuseLightingWithLight<K extends keyof LightTypes>(attrs: FeDiffuseLightingAttributes, type: K, lightAttrs: LightTypes[K]) {
let elem = this.addElement("feDiffuseLighting", attrs) as SVGFilterElement;
this.addElement(type, lightAttrs, elem);
return this;
}
This way when I call it with
.feDiffuseLightingWithLight({ "lighting-color": "#4a7997", result: "textured" }, "feDistantLight", { azimuth: 90, elevation: 50 })
I can only see the azimuth
and elevation
properties within the object since I passed in "feDistantLight"
. Properties from other types of light will give a typescript error.