如何使用TypeScript接口实现类似抽象类的约束效果?
问题解答
能否通过TypeScript接口实现需求
TypeScript的接口属于编译期类型契约,仅用于类型校验,编译后会被完全抹除,本身不具备任何运行时能力,因此不能直接通过接口给对象添加方法实现。但你可以用接口定义统一的类型规范,配合运行时的数据转换逻辑,完全实现你要的调用效果。
可行实现方案
方案1:适配现有代码,给响应数据挂载自定义方法
你可以先定义API返回的原始数据类型,再定义带自定义方法的业务类型,请求成功后遍历数组项挂载方法即可,示例代码如下:
import axios from 'axios' // 定义API返回的原始数据结构(不带自定义方法) interface RawPost { name: string // 其他接口返回的原生字段 } // 业务层使用的Post类型,带自定义方法 interface Post extends RawPost { myCustomGetter: () => string } export async function getPosts(): Promise<Post[]> { try { // 泛型指定原始响应类型为RawPost[] const response = await axios.get<RawPost[]>('https://jsonplaceholder.typicode.com/posts') // 遍历每个项,挂载自定义方法 const postsWithMethod = response.data.map(post => { return { ...post, myCustomGetter() { return this.name } } }) return postsWithMethod } catch (error) { throw error } }
调用时直接使用posts[i].myCustomGetter()即可,完全不需要关心内部实现。如果是/posts2接口,只要修改myCustomGetter的返回逻辑为return this.specialname即可。
方案2:通用工厂函数(多接口复用场景)
如果有多个接口都需要类似的自定义方法规范,可以抽通用逻辑,进一步提高复用性:
// 通用的带自定义getter的类型约束 interface WithCustomGetter { myCustomGetter: () => string } // 通用工厂函数,传入原始数据和getter实现,返回带方法的对象 function createWithMethod<T>(rawData: T, getterImpl: (raw: T) => string): T & WithCustomGetter { return { ...rawData, myCustomGetter() { return getterImpl(rawData) } } } // 调用示例:/posts接口的getPosts方法 export async function getPosts(): Promise<(RawPost & WithCustomGetter)[]> { const response = await axios.get<RawPost[]>('https://jsonplaceholder.typicode.com/posts') return response.data.map(item => createWithMethod(item, (raw) => raw.name)) } // /posts2接口的getPosts2方法 interface RawPost2 { specialname: string } export async function getPosts2(): Promise<(RawPost2 & WithCustomGetter)[]> { const response = await axios.get<RawPost2[]>('xxx/posts2') return response.data.map(item => createWithMethod(item, (raw) => raw.specialname)) }
内容的提问来源于stack exchange,提问作者tiagop
相关产品推荐
相关产品推荐

