假设我们要定义一份配置,如果直接写则没有类型提示,写错字段名或少写字段 TS 也不会报错。
ts
const TIME_UNITS_TRANSLATIONS = {
day: {
singular: 'day',
plural: 'days',
},
hour: {
singular: 'hour',
plural: 'hours',
},
minute: {
singular: 'minute',
plural: 'minutes',
},
second: {
singular: 'second',
plural: 'seconds',
},
millisecond: {
singular: 'millisecond',
plural: 'milliseconds',
},
}
但若加上类型,确实解决了字段提示的问题,但是又会出现新问题:
ts
type ITimeUnit = 'day' | 'hour' | 'minute' | 'second' | 'millisecond'
type IForms = {
singular: string
plural: string
}
const TIME_UNITS_TRANSLATIONS: Record<ITimeUnit, IForms> = {
day: {
singular: 'day',
plural: 'days',
},
hour: {
singular: 'hour',
plural: 'hours',
},
minute: {
singular: 'minute',
plural: 'minutes',
},
second: {
singular: 'second',
plural: 'seconds',
},
millisecond: {
singular: 'millisecond',
plural: 'milliseconds',
},
}
当我们 hover 变量其类型变成
const TIME_UNITS_TRANSLATIONS: Record<ITimeUnit, IForms>
而不加类型之前,VSCode 是能完整提示到字段级别的。这样便于我们观察变量,无需跳转到其定义处就能知道里面有哪些字段。
ts
const TIME_UNITS_TRANSLATIONS: {
day: {
singular: string;
plural: string;
};
hour: {
singular: string;
plural: string;
};
minute: {
singular: string;
plural: string;
};
second: {
singular: string;
plural: string;
};
millisecond: {
singular: string;
plural: string;
};
}

能否一举两得 - satisfies
to the rescue 💉
ts
const TIME_UNITS_TRANSLATIONS = {
day: {
singular: 'day',
plural: 'days',
},
hour: {
singular: 'hour',
plural: 'hours',
},
minute: {
singular: 'minute',
plural: 'minutes',
},
second: {
singular: 'second',
plural: 'seconds',
},
millisecond: {
singular: 'millisecond',
plural: 'milliseconds',
},
} satisfies Record<ITimeUnit, IForms>
这时候 hover 后发现我们平铺的类型定义又回来,而且字段能自动提示。

更进一步 - as const satisfies ...
🔬
能否做到更好?我们试试 as const satisfies ...
ts
const TIME_UNITS_TRANSLATIONS = {
day: {
singular: 'day',
plural: 'days',
},
hour: {
singular: 'hour',
plural: 'hours',
},
minute: {
singular: 'minute',
plural: 'minutes',
},
second: {
singular: 'second',
plural: 'seconds',
},
millisecond: {
singular: 'millisecond',
plural: 'milliseconds',
},
} as const satisfies Record<ITimeUnit, IForms>
此时发现还能具体到字段的值,完美!

第二个例子
这个例子帮助我们更好理解 satisifies
。
ts
type User = {
id: string;
name: string;
age?: number;
};
const alice = {
id: "123",
name: "Alice",
age: 30,
} satisfies User; // ✅ 类型仍然是 { id: string; name: string; age: number }
// 仍然可以访问 alice.age.toFixed(2),因为 age 被推断为 `number` 而不是 `number | undefined`
如果改成普通的类型标注:
ts
const alice: User = {
id: "123",
name: "Alice",
age: 30,
}; // 类型变成了 User 即 { id: string; name: string; age?: number }
alice.age.toFixed(2)
// ^^^^ 'alice.age' is possibly 'undefined'.(18048)
代码将报错因为 age 被推断为number | undefined
而不是 number
:
但实际上我们知道 alice 的 age 并不为空(30
)。
到这里我们就学会了何时在项目中使用 satisifies
了 🎉!
总结
当我们想验证变量类型但不改变类型本身 ,可以试试 satisifies
,打破鱼与熊掌二者不可兼得。
参考
- TypeScript 4.9 The
satisfies
Operator www.typescriptlang.org/docs/handbo...