发布于 2025年12月23日
译:“无”也是一种“有”
原文: https://kyleshevlin.com/nothing-is-something/
作者: Kyle Shevlin
译者: Gemini 3 Pro High
我真的需要更多人去观看 Sandi Metz 的 “Nothing is Something”(无也是一种有),这样当我在代码中应用其中的教训时,就不会收到奇怪的目光了。
今天我正在处理类似下面这样一个问题。想象你有一个键值对对象,其中键代表某种状态,而值则是对该状态的某种转换。
// Just some arbitrary state for our example
type State = {
count: number
createdAt: Date
isActive: boolean
name: string
}
type Transform = <T>(x: T) => T
const STATE_TRANSFORMS: Partial<Record<keyof State, Transform>> = {
count: x => x * 2,
name: x => x.toUpperCase(),
}
这些转换本身并不特别重要,但请注意,我并没有为 State 类型中的每一个键都提供转换。
现在,如果你要编写一个函数来运行这些转换,你可能会想这样做:
function transformStates(state: State) {
const nextState: State = {}
for (const key of state) {
const transform = STATE_TRANSFORMS[key]
// This handles the condition at the last possible moment
// and it results in two separate ways of managing the state
if (transform) {
nextState[key] = transform(state[key])
} else {
nextState[key] = state[key]
}
}
return nextState
}
但我更喜欢这样做:
const identity = x => x
function transformStates(state) {
const nextState = {}
for (const key of state) {
// Condition is handled a step earlier and we've narrowed
// the type of `transform` from `Transform | undefined`
// to just `Transform`, simplifying the next step
const transform = STATE_TRANSFORMS[key] ?? identity
nextState[key] = transform(state[key])
}
return nextState
}
因为,正如演讲标题所暗示的,什么都不做(doing nothing)本身就是在做某事(doing something)。
你可能会争辩说我在这里进行了不必要的函数调用,但我认为为了代码的简洁,这是一个值得的权衡。
我们可以利用这种模式——即识别“无”(也就是默认行为)并为其提供功能——作为简化代码的一种方式,主要是通过减少过多的条件判断,而条件判断往往是复杂性的来源。
请观看那个演讲。你会因此成为一名更好的程序员。