Skip to main content

Using "sel" References

The sel object is a special import that allows you to easily reference components with a bit more type-safety than a string. It can also be more ergonomic than typing out a port selector.

import { sel } from "tscircuit"

export default () => (
<board width="10mm" height="10mm">
<resistor
resistance="1k"
footprint="0402"
name="R1"
/>
<capacitor
capacitance="1000pF"
footprint="0402"
name="C1"
/>
<trace from={sel.R1.pin1} to={sel.C1.pos} />
</board>
)

The sel can be thought of as a very large mapping of conventional strings.

Here are some sel expressions and their corresponding string:

import { sel } from "tscircuit"

sel.R1.pin1
// ".R1 > .pin1"

sel.C1.pos
// ".C1 > .pos"

sel.net.GND
// "net.GND"

sel.U1.GPIO1
// ".U1 > .GPIO1"

Type-Safe Chip Pin References

The sel object provides enhanced type safety when working with chips by allowing you to reference pins with proper TypeScript types. There are two advanced ways to use sel with chips:

You can pass a chip component to sel to get fully type-safe pin accessors:

import { MyChip } from "./my-chip"

const selectors = {
U1: sel.U1(MyChip)
}

export const MyChipWithSomeTraces = () => (
<group>
<MyChip name="U1" />
<trace from={selectors.U1.VCC} to="net.VCC" />
<trace from={selectors.U1.GND} to="net.GND" />
</group>
)
info

In order for type-safe selectors to work, you need to define your chip component with a ChipProps type, like this:

import { ChipProps } from "tscircuit"

const pinLabels = {
VCC: string
GND: string
} as const

const MyChip = (props: ChipProps<typeof pinLabels>) => (
<chip {...props} pinLabels={pinLabels} />
)

sel.U1(MyChip).VCC is the same as sel.U1.VCC, however, when we pass MyChip to sel.U1, TypeScript will check that MyChip has a pin called VCC and will error if it doesn't.

import { sel } from "tscircuit"
import { MyChip } from "./my-chip"

sel.U1(MyChip).VCC
// ".U1 > .VCC"

sel.U1(MyChip).GND
// ".U1 > .GND"

// TypeScript will error on non-existent pins!
// sel.U1(MyChip).DOES_NOT_EXIST -> ERROR!

Generic Pin Selectors (no chip needed!)

You can also use TypeScript generics to define custom pin types directly:

import { sel } from "tscircuit"

// Define custom pin types using generics
const selU2 = sel.U2<"custompin1" | "custompin2">()

selU2.custompin1 // Returns ".U2 > .custompin1"
selU2.custompin2 // Returns ".U2 > .custompin2"

// TypeScript will error on non-existent pins!
// selU2.doesnotexist // TypeScript error!

So sel is a more type-safe, conventional way of writing port selectors.