// FinalResponse.ts import { Reaction } from'./Reaction' exporttypeFinalResponse = { totalScore: number headingsPenalty: number sentencesPenalty: number charactersPenalty: number wordsPenalty: number headings: string[] sentences: string[] words: string[] links: { href: string; text: string }[] exceeded: { exceededSentences: string[] repeatedWords: { word: string; count: number }[] } reactions: { likes: Reaction unicorns: Reaction explodingHeads: Reaction raisedHands: Reaction fire: Reaction } }上面的类型定义看似清晰,但如果现在我想新增一个「爱心」的reaction,意味着我要去修改多个地方:
// Reaction.ts exporttypeReaction = { count: number percentage: number } // 改进后的FinalResponse.ts exporttypeReactionMap = Record<string, Reaction> exporttypeFinalResponse = { totalScore: number headingsPenalty: number sentencesPenalty: number charactersPenalty: number wordsPenalty: number headings: string[] sentences: string[] words: string[] links: { href: string; text: string }[] exceeded: { exceededSentences: string[] repeatedWords: { word: string; count: number }[] } reactions: ReactionMap }为什么这样更好?
• 降低耦合:代码变动集中在更小范围内,便于维护。
// 堆代码 duidaima.com // 优化后的FinalResponse.ts import { Reaction } from'./Reaction' typeAllowedReactions = | 'likes' | 'unicorns' | 'explodingHeads' | 'raisedHands' | 'fire' exporttypeReactionMap = { [key inAllowedReactions]: Reaction } exporttypeFinalResponse = { totalScore: number headingsPenalty: number sentencesPenalty: number charactersPenalty: number wordsPenalty: number headings: string[] sentences: string[] words: string[] links: { href: string; text: string }[] exceeded: { exceededSentences: string[] repeatedWords: { word: string; count: number }[] } reactions: ReactionMap }这样做的好处就是我们不仅保留了原先的灵活性,还能严格控制reaction的类型,避免随意添加未知的类型,确保了代码的安全性。
// calculator.ts exportconst calculateScore = ( headings: string[], sentences: string[], words: string[], totalPostCharactersCount: number, links: { href: string; text: string }[], reactions: ReactionMap, ): FinalResponse => { // 计算逻辑放在这里... }三、总结一下