Skip to content

Commit 0a9f83d

Browse files
ShiboSoftwareDevYour Name
andauthored
Refactor: Improve type safety in processors (#33)
Co-authored-by: Your Name <you@example.com>
1 parent ce25e07 commit 0a9f83d

8 files changed

+97
-95
lines changed

lib/circuitJsonToSpice.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ import type {
44
AnyCircuitElement,
55
SimulationSwitch,
66
SimulationVoltageProbe,
7+
SourceSimpleDiode,
8+
SourceSimpleMosfet,
9+
SourceSimpleSwitch,
10+
SourceSimpleTransistor,
711
} from "circuit-json"
812
import { getSourcePortConnectivityMapFromCircuitJson } from "circuit-json-to-connectivity-map"
913
import { su } from "@tscircuit/circuit-json-util"
@@ -208,7 +212,7 @@ export function circuitJsonToSpice(
208212
case "simple_switch": {
209213
spiceComponent = processSimpleSwitch({
210214
netlist,
211-
component,
215+
component: component as SourceSimpleSwitch,
212216
nodes,
213217
simulationSwitchMap,
214218
})
@@ -221,7 +225,7 @@ export function circuitJsonToSpice(
221225
case "simple_diode": {
222226
spiceComponent = processSimpleDiode({
223227
netlist,
224-
component,
228+
component: component as SourceSimpleDiode,
225229
componentPorts,
226230
nodeMap,
227231
})
@@ -234,7 +238,7 @@ export function circuitJsonToSpice(
234238
case "simple_mosfet": {
235239
spiceComponent = processSimpleMosfet({
236240
netlist,
237-
component,
241+
component: component as SourceSimpleMosfet,
238242
componentPorts,
239243
nodeMap,
240244
})
@@ -243,7 +247,7 @@ export function circuitJsonToSpice(
243247
case "simple_transistor": {
244248
spiceComponent = processSimpleTransistor({
245249
netlist,
246-
component,
250+
component: component as SourceSimpleTransistor,
247251
componentPorts,
248252
nodeMap,
249253
})
@@ -269,13 +273,17 @@ export function circuitJsonToSpice(
269273
nodeMap,
270274
)
271275

272-
processSimulationExperiment(
273-
netlist,
274-
circuitJson.find((elm) => elm.type === "simulation_experiment"),
275-
simulationProbes,
276-
sourceTraces,
277-
nodeMap,
276+
const simulationExperiment = circuitJson.find(
277+
(elm) => elm.type === "simulation_experiment",
278278
)
279+
if (simulationExperiment)
280+
processSimulationExperiment(
281+
netlist,
282+
simulationExperiment,
283+
simulationProbes,
284+
sourceTraces,
285+
nodeMap,
286+
)
279287

280288
return netlist
281289
}

lib/processors/process-simulation-current-sources.ts

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,36 +11,36 @@ export const processSimulationCurrentSources = (
1111
for (const simSource of simulationCurrentSources) {
1212
if (simSource.type !== "simulation_current_source") continue
1313

14-
if ((simSource as any).is_dc_source === false) {
14+
if (simSource.is_dc_source === false) {
1515
// AC/PULSE Source
16-
const positivePortId = (simSource as any).terminal1_source_port_id
17-
const negativePortId = (simSource as any).terminal2_source_port_id
16+
const positivePortId = simSource.terminal1_source_port_id
17+
const negativePortId = simSource.terminal2_source_port_id
1818

1919
if (positivePortId && negativePortId) {
2020
const positiveNode = nodeMap.get(positivePortId) || "0"
2121
const negativeNode = nodeMap.get(negativePortId) || "0"
2222

2323
let value = ""
24-
const wave_shape = (simSource as any).wave_shape
24+
const wave_shape = simSource.wave_shape
2525
if (wave_shape === "sinewave") {
2626
const i_offset = 0 // not provided
27-
const i_peak = ((simSource as any).peak_to_peak_current ?? 0) / 2
28-
const freq = (simSource as any).frequency ?? 0
27+
const i_peak = (simSource.peak_to_peak_current ?? 0) / 2
28+
const freq = simSource.frequency ?? 0
2929
const delay = 0
3030
const damping_factor = 0
31-
const phase = (simSource as any).phase ?? 0
31+
const phase = simSource.phase ?? 0
3232
if (freq > 0) {
3333
value = `SIN(${i_offset} ${i_peak} ${freq} ${delay} ${damping_factor} ${phase})`
3434
} else {
3535
value = `DC ${i_peak}`
3636
}
3737
} else if (wave_shape === "square") {
3838
const i_initial = 0
39-
const i_pulsed = (simSource as any).peak_to_peak_current ?? 0
40-
const freq = (simSource as any).frequency ?? 0
39+
const i_pulsed = simSource.peak_to_peak_current ?? 0
40+
const freq = simSource.frequency ?? 0
4141
const period_from_freq = freq === 0 ? Infinity : 1 / freq
42-
const period = (simSource as any).period ?? period_from_freq
43-
const duty_cycle = (simSource as any).duty_cycle ?? 0.5
42+
const period = period_from_freq
43+
const duty_cycle = simSource.duty_cycle ?? 0.5
4444
const pulse_width = period * duty_cycle
4545
const delay = 0
4646
const rise_time = "1n"
@@ -50,14 +50,14 @@ export const processSimulationCurrentSources = (
5050

5151
if (value) {
5252
const currentSourceCmd = new CurrentSourceCommand({
53-
name: (simSource as any).simulation_current_source_id,
53+
name: simSource.simulation_current_source_id,
5454
positiveNode,
5555
negativeNode,
5656
value,
5757
})
5858

5959
const spiceComponent = new SpiceComponent(
60-
(simSource as any).simulation_current_source_id,
60+
simSource.simulation_current_source_id,
6161
currentSourceCmd,
6262
[positiveNode, negativeNode],
6363
)
@@ -66,27 +66,27 @@ export const processSimulationCurrentSources = (
6666
}
6767
} else {
6868
// DC Source
69-
const positivePortId = (simSource as any).positive_source_port_id
70-
const negativePortId = (simSource as any).negative_source_port_id
69+
const positivePortId = simSource.positive_source_port_id
70+
const negativePortId = simSource.negative_source_port_id
7171

7272
if (
7373
positivePortId &&
7474
negativePortId &&
7575
"current" in simSource &&
76-
(simSource as any).current !== undefined
76+
simSource.current !== undefined
7777
) {
7878
const positiveNode = nodeMap.get(positivePortId) || "0"
7979
const negativeNode = nodeMap.get(negativePortId) || "0"
8080

8181
const currentSourceCmd = new CurrentSourceCommand({
82-
name: (simSource as any).simulation_current_source_id,
82+
name: simSource.simulation_current_source_id,
8383
positiveNode,
8484
negativeNode,
85-
value: `DC ${(simSource as any).current}`,
85+
value: `DC ${simSource.current}`,
8686
})
8787

8888
const spiceComponent = new SpiceComponent(
89-
(simSource as any).simulation_current_source_id,
89+
simSource.simulation_current_source_id,
9090
currentSourceCmd,
9191
[positiveNode, negativeNode],
9292
)

lib/processors/process-simulation-experiment.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type {
2-
AnyCircuitElement,
2+
SimulationExperiment,
33
SimulationVoltageProbe,
44
SourceTrace,
55
} from "circuit-json"
@@ -8,7 +8,7 @@ import { formatNumberForSpice } from "./helpers"
88

99
export const processSimulationExperiment = (
1010
netlist: SpiceNetlist,
11-
simExperiment: AnyCircuitElement | undefined,
11+
simExperiment: SimulationExperiment,
1212
simulationProbes: SimulationVoltageProbe[],
1313
sourceTraces: SourceTrace[],
1414
nodeMap: Map<string, string>,
@@ -64,15 +64,15 @@ export const processSimulationExperiment = (
6464

6565
if (
6666
nodesToProbe.size > 0 &&
67-
(simExperiment as any).experiment_type?.includes("transient")
67+
simExperiment.experiment_type?.includes("transient")
6868
) {
6969
netlist.printStatements.push(`.PRINT TRAN ${[...nodesToProbe].join(" ")}`)
7070
}
7171
}
7272

73-
const timePerStep = (simExperiment as any).time_per_step
74-
const endTime = (simExperiment as any).end_time_ms
75-
const startTimeMs = (simExperiment as any).start_time_ms
73+
const timePerStep = simExperiment.time_per_step
74+
const endTime = simExperiment.end_time_ms
75+
const startTimeMs = simExperiment.start_time_ms
7676

7777
if (timePerStep && endTime) {
7878
// circuit-json values are in ms, SPICE requires seconds

lib/processors/process-simulation-voltage-sources.ts

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,57 @@
1-
import type { AnyCircuitElement } from "circuit-json"
1+
import type { AnyCircuitElement, SimulationVoltageSource } from "circuit-json"
22
import { SpiceComponent } from "lib/spice-classes/SpiceComponent"
33
import type { SpiceNetlist } from "lib/spice-classes/SpiceNetlist"
44
import { VoltageSourceCommand } from "lib/spice-commands"
55

66
export const processSimulationVoltageSources = (
77
netlist: SpiceNetlist,
8-
simulationVoltageSources: AnyCircuitElement[],
8+
simulationVoltageSources: SimulationVoltageSource[],
99
nodeMap: Map<string, string>,
1010
) => {
1111
for (const simSource of simulationVoltageSources) {
1212
if (simSource.type !== "simulation_voltage_source") continue
1313

14-
if ((simSource as any).is_dc_source === false) {
14+
if (simSource.is_dc_source === false) {
1515
// AC Source
1616
if (
1717
"terminal1_source_port_id" in simSource &&
1818
"terminal2_source_port_id" in simSource &&
19-
(simSource as any).terminal1_source_port_id &&
20-
(simSource as any).terminal2_source_port_id
19+
simSource.terminal1_source_port_id &&
20+
simSource.terminal2_source_port_id
2121
) {
2222
const positiveNode =
23-
nodeMap.get((simSource as any).terminal1_source_port_id) || "0"
23+
nodeMap.get(simSource.terminal1_source_port_id) || "0"
2424
const negativeNode =
25-
nodeMap.get((simSource as any).terminal2_source_port_id) || "0"
25+
nodeMap.get(simSource.terminal2_source_port_id) || "0"
2626

2727
let value = ""
28-
const wave_shape = (simSource as any).wave_shape
28+
const wave_shape = simSource.wave_shape
2929
if (wave_shape === "sinewave") {
3030
const v_offset = 0 // not provided in circuitJson
31-
const v_peak = (simSource as any).voltage ?? 0
32-
const freq = (simSource as any).frequency ?? 0
31+
const v_peak = simSource.voltage ?? 0
32+
const freq = simSource.frequency ?? 0
3333
const delay = 0 // not provided in circuitJson
3434
const damping_factor = 0 // not provided in circuitJson
35-
const phase = (simSource as any).phase ?? 0
35+
const phase = simSource.phase ?? 0
3636
if (freq > 0) {
3737
value = `SIN(${v_offset} ${v_peak} ${freq} ${delay} ${damping_factor} ${phase})`
3838
} else {
39-
value = `DC ${(simSource as any).voltage ?? 0}`
39+
value = `DC ${simSource.voltage ?? 0}`
4040
}
4141
} else if (wave_shape === "square") {
4242
const v_initial = 0
43-
const v_pulsed = (simSource as any).voltage ?? 0
44-
const freq = (simSource as any).frequency ?? 0
43+
const v_pulsed = simSource.voltage ?? 0
44+
const freq = simSource.frequency ?? 0
4545
const period_from_freq = freq === 0 ? Infinity : 1 / freq
46-
const period = (simSource as any).period ?? period_from_freq
47-
const duty_cycle = (simSource as any).duty_cycle ?? 0.5
46+
const period = period_from_freq
47+
const duty_cycle = simSource.duty_cycle ?? 0.5
4848
const pulse_width = period * duty_cycle
4949
const delay = 0
5050
const rise_time = "1n"
5151
const fall_time = "1n"
5252
value = `PULSE(${v_initial} ${v_pulsed} ${delay} ${rise_time} ${fall_time} ${pulse_width} ${period})`
53-
} else if ((simSource as any).voltage !== undefined) {
54-
value = `DC ${(simSource as any).voltage}`
53+
} else if (simSource.voltage !== undefined) {
54+
value = `DC ${simSource.voltage}`
5555
}
5656

5757
if (value) {
@@ -72,18 +72,14 @@ export const processSimulationVoltageSources = (
7272
}
7373
} else {
7474
// DC Source (is_dc_source is true or undefined)
75-
const positivePortId =
76-
(simSource as any).positive_source_port_id ??
77-
(simSource as any).terminal1_source_port_id
78-
const negativePortId =
79-
(simSource as any).negative_source_port_id ??
80-
(simSource as any).terminal2_source_port_id
75+
const positivePortId = simSource.positive_source_port_id
76+
const negativePortId = simSource.negative_source_port_id
8177

8278
if (
8379
positivePortId &&
8480
negativePortId &&
8581
"voltage" in simSource &&
86-
(simSource as any).voltage !== undefined
82+
simSource.voltage !== undefined
8783
) {
8884
const positiveNode = nodeMap.get(positivePortId) || "0"
8985
const negativeNode = nodeMap.get(negativePortId) || "0"

lib/processors/simple-diode.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { SpiceNetlist } from "lib/spice-classes/SpiceNetlist"
22
import { SpiceComponent } from "lib/spice-classes/SpiceComponent"
33
import { DiodeCommand } from "lib/spice-commands"
4-
import type { AnyCircuitElement } from "circuit-json"
4+
import type { SourcePort, SourceSimpleDiode } from "circuit-json"
55

66
export const processSimpleDiode = ({
77
netlist,
@@ -10,20 +10,20 @@ export const processSimpleDiode = ({
1010
nodeMap,
1111
}: {
1212
netlist: SpiceNetlist
13-
component: AnyCircuitElement
14-
componentPorts: AnyCircuitElement[]
13+
component: SourceSimpleDiode
14+
componentPorts: SourcePort[]
1515
nodeMap: Map<string, string>
1616
}): SpiceComponent | null => {
1717
if ("name" in component) {
1818
const anodePort = componentPorts.find(
19-
(p: any) =>
19+
(p) =>
2020
p.name?.toLowerCase() === "anode" || p.port_hints?.includes("anode"),
21-
) as any
21+
)
2222
const cathodePort = componentPorts.find(
23-
(p: any) =>
23+
(p) =>
2424
p.name?.toLowerCase() === "cathode" ||
2525
p.port_hints?.includes("cathode"),
26-
) as any
26+
)
2727
const positiveNode = nodeMap.get(anodePort?.source_port_id ?? "") || "0"
2828
const negativeNode = nodeMap.get(cathodePort?.source_port_id ?? "") || "0"
2929

lib/processors/simple-mosfet.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { SpiceNetlist } from "lib/spice-classes/SpiceNetlist"
22
import { SpiceComponent } from "lib/spice-classes/SpiceComponent"
33
import { MOSFETCommand } from "lib/spice-commands"
4-
import type { AnyCircuitElement } from "circuit-json"
4+
import type { SourcePort, SourceSimpleMosfet } from "circuit-json"
55

66
export const processSimpleMosfet = ({
77
netlist,
@@ -10,23 +10,22 @@ export const processSimpleMosfet = ({
1010
nodeMap,
1111
}: {
1212
netlist: SpiceNetlist
13-
component: AnyCircuitElement
14-
componentPorts: AnyCircuitElement[]
13+
component: SourceSimpleMosfet
14+
componentPorts: SourcePort[]
1515
nodeMap: Map<string, string>
1616
}): SpiceComponent | null => {
1717
if ("name" in component) {
1818
const drainPort = componentPorts.find(
19-
(p: any) =>
19+
(p) =>
2020
p.name?.toLowerCase() === "drain" || p.port_hints?.includes("drain"),
21-
) as any
21+
)
2222
const gatePort = componentPorts.find(
23-
(p: any) =>
24-
p.name?.toLowerCase() === "gate" || p.port_hints?.includes("gate"),
25-
) as any
23+
(p) => p.name?.toLowerCase() === "gate" || p.port_hints?.includes("gate"),
24+
)
2625
const sourcePort = componentPorts.find(
27-
(p: any) =>
26+
(p) =>
2827
p.name?.toLowerCase() === "source" || p.port_hints?.includes("source"),
29-
) as any
28+
)
3029

3130
const drainNode = nodeMap.get(drainPort?.source_port_id ?? "") || "0"
3231
const gateNode = nodeMap.get(gatePort?.source_port_id ?? "") || "0"
@@ -35,8 +34,8 @@ export const processSimpleMosfet = ({
3534
// For 3-pin MOSFETs, substrate is typically connected to source
3635
const substrateNode = sourceNode
3736

38-
const channel_type = (component as any).channel_type ?? "n"
39-
const mosfet_mode = (component as any).mosfet_mode ?? "enhancement"
37+
const channel_type = component.channel_type ?? "n"
38+
const mosfet_mode = component.mosfet_mode ?? "enhancement"
4039

4140
const modelType = `${channel_type.toUpperCase()}MOS`
4241
const modelName = `${modelType}_${mosfet_mode.toUpperCase()}`

0 commit comments

Comments
 (0)