如何获取TypeScript函数参数的初始默认类型并对其进行内联扩展
解决方案
TypeScript 本身没有你提到的initial/default这类直接引用参数默认推导类型的关键字,但针对 GraphQL Nexus 的场景,有两种可行方案可以保留自动类型推导能力的同时扩展参数类型:
方案1:使用 Nexus 原生sourceType配置(最优解)
Nexus 原生支持通过sourceType配置扩展原始数据源的类型,不需要额外手动做类型推导,定义后isTypeOf的data参数会自动合并definition生成的字段类型和你定义的额外字段类型:
import { objectType } from 'nexus' export const Item = objectType({ name: 'Item', // 在这里声明源数据额外携带的字段类型 sourceType: { kind: string }, isTypeOf(data) { // 此时 data 自动具备 { name: string, kind: string } 类型 return data.kind === 'item' }, definition(t) { t.string('name') // 所有字段定义修改后,data 的基础类型会自动同步 } })
方案2:通用类型推导方案(不依赖 Nexus 内置能力)
如果你的场景比较特殊,无法使用上述原生配置,可以通过 TypeScript 内置的类型工具自动提取初始推导类型再交叉扩展,全程不需要手动声明基础字段类型:
import type { ObjectTypeConfig } from 'nexus' // 先定义除 isTypeOf 之外的配置,自动推导基础字段类型 const baseConfig = { definition(t) { t.string('name') // 所有复杂字段统一在这里维护,只需要修改一次 } } satisfies Partial<ObjectTypeConfig<any, any>> // 自动提取 Nexus 推导的初始 data 类型 type InitialData = Parameters<NonNullable<ObjectTypeConfig<typeof baseConfig, any>['isTypeOf']>>[0] // 导出完整配置,扩展 data 类型 export const Item = { ...baseConfig, isTypeOf(data: InitialData & { kind: string }) { // data 类型自动同步 definition 的修改,同时具备额外的 kind 字段类型 } }
两种方案都不需要手动写全所有字段的类型,完全保留了 Nexus 自动类型推导的优势,后续修改definition的字段定义时,data的类型会自动同步更新,不需要额外维护。
内容的提问来源于stack exchange,提问作者João Haas
相关产品推荐
相关产品推荐

