Today I learned about Typescript execute (I’m using it on my website now too 😆). It’s a CLI alternative to node for running Typescript & ESM!
TIL that there’s a TS utility type that does the opposite of Partial
.
Want to make it so that people need to provide some sort of generic argument if they don’t use some predefined defaults for your TS code. Check this out:
type NoInfer<T> = [T][T extends any ? 0 : never]
type QT<T> = 'first' | 'second' | T
type Yolo<T> = {
data: QT<T>
}
function doSomething<T = void>(args: Yolo<NoInfer<T>>): null {
// do something
return null
}
doSomething({data: 'first'}) // okay
doSomething({data: 'three'}) // not okay
doSomething<'three'>({data: 'three'}) //okay
Alright, so I’ve been writing TS for a while and was never really sure why we
needed these .d.ts
files… until today.
The purpose of these files is so that authors/the community can backport popular JS libraries with TS type definitions. This allows library authors the freedom to keep on writing their JS code but allows users of TS to benefit with working code and the typings they need.
These typings probably exist in something like Definitely Typed. However, at work, we’re using a mix of JS and TS (JS is for the jest setup code) and therefore we were required to have ambient TS files so that our TS test code could benefit from the typings related to our JS files.
We are using module aliasing for our TestUtils
so that we can do things like
import { render } from 'TestUtils'
. Under the hood, the render function is
just a nicely wrapped render function from react-testing-library and so the
return types are the same. There was a bug where if I tried to import the
RenderResult
from the testing library, VS code’s TS language server would yell
at me for having an undefined module. The following code highlights the
fix/issue.
// TYPESCRIPT IS A PAIN
// https://stackoverflow.com/questions/39040108/import-class-in-definition-file-d-ts/51114250#51114251
declare module "TestUtils" {
export function render(
v: any,
other?: { initialState?: any }
): import("@testing-library/react").RenderResult
}
// doesn't work
import { RenderResult } from "@testing-library/react"
declare module "TestUtils" {
export function render(v: any, other?: { initialState?: any }): RenderResult
}
React.FC
was more meant to help beginners get more comfortable writing React
components with TS but honestly, the cons of using it (always having the ability
to pass children
to your component even though you might not be rendering said
children
) make me want to not use it.
If you’re wanting to type children
, you can do:
type Props = {
children?: React.ReactNode
}
Turns out TS has some conditional types!
T extends U ? X : Y
If T extends U, then T is type X otherwise it is type Y.
There’s a neat little utility type in TypeScript that lets you reach into a function and discern the types of the function arguments.
Parameters<(s: string) => void>
// [s: string]