You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

移除TypeScript代码中any类型,实现泛型与Partial约束的类型安全

解决TypeScript泛型联合类型的类型安全问题

你的问题核心是TypeScript无法通过type字段的判断自动缩小泛型T的范围,导致Partial<T>无法直接匹配Partial<SportJournal>或Partial<ArtJournal>。下面提供两种类型安全的解决方案,完全移除any类型:

方案一:使用类型谓词(Type Predicates)收窄泛型类型

定义专门的类型判断函数,明确告诉TypeScript当前JournalState的具体类型,从而让编译器正确推断Partial<T>的类型:

type SportJournal = { type: 'S', sport: boolean, id: string}
type ArtJournal = { type: 'A', art: boolean, id: string}
type Journal = SportJournal | ArtJournal;
type JournalState<T extends Journal> = {state: string, journal: T}

const updateSportJournal = (journal: Partial<SportJournal>) => { console.log(journal)}
const updateArtJournal = (journal: Partial<ArtJournal>) => { console.log(journal)}

// 定义类型谓词函数,明确判断JournalState的具体类型
function isSportJournalState<T extends Journal>(state: JournalState<T>): state is JournalState<SportJournal> {
  return state.journal.type === 'S';
}

function isArtJournalState<T extends Journal>(state: JournalState<T>): state is JournalState<ArtJournal> {
  return state.journal.type === 'A';
}

const updateJournalState = <T extends Journal>(journalState: JournalState<T>, journal: Partial<T>) => {
  if (isSportJournalState(journalState)) {
    updateSportJournal(journal); // 无需any,类型自动匹配
  } else if (isArtJournalState(journalState)) {
    updateArtJournal(journal);
  }
}

方案二:使用联合类型参数确保类型匹配

直接将函数参数定义为联合类型,强制journalState和journal的类型一一对应,从根源避免类型不匹配的问题:

type SportJournal = { type: 'S', sport: boolean, id: string}
type ArtJournal = { type: 'A', art: boolean, id: string}
type Journal = SportJournal | ArtJournal;
type JournalState<T extends Journal> = {state: string, journal: T}

const updateSportJournal = (journal: Partial<SportJournal>) => { console.log(journal)}
const updateArtJournal = (journal: Partial<ArtJournal>) => { console.log(journal)}

// 定义联合类型的参数,确保journalState和journal类型匹配
type JournalUpdateParams =
  | { journalState: JournalState<SportJournal>, journal: Partial<SportJournal> }
  | { journalState: JournalState<ArtJournal>, journal: Partial<ArtJournal> };

const updateJournalState = ({ journalState, journal }: JournalUpdateParams) => {
  if (journalState.journal.type === 'S') {
    updateSportJournal(journal);
  } else {
    updateArtJournal(journal);
  }
}

验证调用

两种方案都支持类型安全的调用,编译器会自动检查参数类型是否匹配:

// 正确调用:运动日志
const sportState: JournalState<SportJournal> = { state: 'active', journal: { type: 'S', sport: true, id: '1' } };
updateJournalState(sportState, { sport: false });

// 正确调用:艺术日志
const artState: JournalState<ArtJournal> = { state: 'draft', journal: { type: 'A', art: true, id: '2' } };
updateJournalState(artState, { art: false });

内容的提问来源于stack exchange,提问作者sandrozbinden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 12:40:01