2024-07-25


Typescript generics and indexed access types
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.
Go back to all posts

2024-04-22


Typescript Record<>
In Typescript there is apparently something called Record<> which allows you to create an object type without using {}.
For example:
Record<string, Pattern>
is the same as
{ [key: string]: Pattern }
but imo looks a bit more readable. 😊
Go back to all posts

2023-10-20


Typescript - generics
In Typescript there’s something called generics that allows you to write functions or classes that can defined with a generic type parameter (placeholder) that will be replaced by the actual type that’s passed into the function.
This allows us to write more flexible functions and up with less duplicated code.
Go back to all posts

2023-10-19


Go back to all posts

2023-10-18


Typescript project conversion
I converted a project to Typescript (not perfectly but 0 errors at least) and found out some interesting things!

Async return type

For normal functions you could do something like
function func(): string {}
but if it’s async you need to surround the type with Promise<>
async function func(): Promise<string> {}

Inline type annotation for object

I had an object as a parameter and had to do something like this:
export function editMode({ selectedList, listItemsUl, API_BASE, headerName }: {selectedList: List, listItemsUl: HTMLUListElement, API_BASE: string, headerName: HTMLDivElement })
If you’re feeling less silly you could do this:
interface EditModeParams { 
selectedList: List; 
listItemsUl: HTMLUListElement; 
API_BASE: string; 
headerName: HTMLDivElement; } 
export function editMode(params: EditModeParams) {}
I also had to do this but using as, for example
itemListArray.push({ title: listItemInput.value, checked: false } as {title: string, checked: boolean});

Type cast event targets

I found that I had to cast the targets as actual elements to use things like .value properly.
let currentTarget = e.target as HTMLInputElement;

Inlay hints

Kind of wish I had this enabled before converting everything but there is a feature in VSCode which inlays the inferred types inline so you can see if they match with the actual types you want!
To enable them search for typescript inlay in Settings and enable the ones you want. I enabled everything 😇
You can also configure the color with
"editorInlayHint.background": "red",
"editorInlayHint.foreground": "black"

cssText

Apparently .style doesn’t work in Typescript so you have to type .style.cssText instead!
Go back to all posts

2023-10-17


Typescript type casting
Typescript has something called type casting which can be used if you want a more specific type.
For example
const myForm = document.querySelector("#my-form");
would give an Element type but maybe we want a more specific type. We could do type casting:
const myForm = document.querySelector("#my-form") as HTMLFormElement;
If we do this it’s more apparent that myForm really is a HTML form element.
We can do the same thing with the e in an event callback function which by default has an any type. By doing this instead e: UIEvent we make it obvious that we’re working with some kind of UI event.
Typescript - variables
Explicit type annotation:
let movieTitle: string;
let movieLength: number;
let isCategoryAction: boolean;
Implicit type annotation (type inference):
let tvSerie = "La Brea";
let isDrama = true;
Any type Should not be used unless necessary
let director: any = "Cristopher Nolan";
director = 10;
director = true;
director();
Go back to all posts

2023-10-12


Go back to all posts