TypeScript移除any类型遇阻:MSGraph API相关代码类型规范求助
移除TypeScript代码中的any类型并适配MS Graph API类型
先统一定义核心类型(可新建types.ts文件存放),明确所有数据结构:
// types.ts export interface BirthdayPerson { id: string; displayName: string; birthday: string; // MS Graph返回的生日为ISO格式字符串,如"1990-05-15" picture?: string; // 头像的Blob URL } // MS Graph用户列表返回的单用户结构(仅保留业务所需字段) export interface GraphUser { id: string; displayName: string; } // MS Graph分页响应通用结构 export interface GraphPaginatedResponse<T> { value: T[]; '@odata.nextLink'?: string; } // 获取用户生日的接口返回结构 export interface GraphBirthdayResponse { value: string; }
改造graph.ts
将分页请求函数改为泛型,彻底移除any,明确返回类型:
// graph.ts async function callMsGraph(accessToken: string, endpoint: string): Promise<Response> { const headers = new Headers(); const bearer = `Bearer ${accessToken}`; headers.append('Authorization', bearer); const options = { method: 'GET', headers, }; try { return fetch(endpoint, options); } catch (error) { console.error(error); throw error; } } export const callMsGraphWithoutPagination = async <T>( accessToken: string, url: string, dataToReturn: T[] = [] ): Promise<T[]> => { try { const data = await callMsGraph(accessToken, url); const dataJson = await data.json() as GraphPaginatedResponse<T>; const newData = dataToReturn.concat(dataJson.value); if (dataJson['@odata.nextLink']) { const NEXT_URL = dataJson['@odata.nextLink'].split('/v1.0')[1]; return await callMsGraphWithoutPagination( accessToken, `${process.env.REACT_APP_GRAPH_URL}${NEXT_URL}`, newData ); } return newData; } catch (error) { console.error(error); throw error; } }; export default callMsGraph;
改造useUsers.tsx
明确所有变量类型,替换掉所有any:
// useUsers.tsx import { GraphUser, GraphBirthdayResponse, BirthdayPerson } from './types'; export const useUsers = () => { const token = useToken(); const [users, setUsers] = React.useState<BirthdayPerson[]>([]); React.useEffect(() => { if (!token) return; callMsGraphWithoutPagination<GraphUser>(token, graphConfig.usersEndpoint) .then(async (usersData) => { const processedData = await Promise.all( usersData.map(async (user) => { // 获取用户生日 const birthdayRes = await callMsGraph(token, graphConfig.userBirthdayEndpoint(user.id)); const birthdayJson = await birthdayRes.json() as GraphBirthdayResponse; // 获取用户头像 const imageRes = await callMsGraph(token, graphConfig.userPhotoEndpoint(user.id)); const blob = await imageRes.blob(); const returnElement: BirthdayPerson = { displayName: user.displayName, birthday: birthdayJson.value, id: user.id, }; if (blob) { window.URL = window.URL || window.webkitURL; returnElement.picture = window.URL.createObjectURL(blob); } return returnElement; }) ); setUsers(processedData); }) .catch(error => console.error('获取用户数据失败:', error)); }, [token]); return users; };
改造helpers.ts
移除所有any,明确参数和返回类型:
// helpers.ts import { BirthdayPerson } from './types'; interface IUpdateData { slideCount: number; } const sortAndFilterBirthdays = (people: BirthdayPerson[], daysToGet: number): BirthdayPerson[] => people .sort((firstEl, secondEl) => sortDate(firstEl.birthday, secondEl.birthday)) .filter(({ birthday }) => filterByAmountOfDays({ date: birthday, daysAfter: daysToGet })); const getBirthdays = (people: BirthdayPerson[], daysToGet: number): BirthdayPerson[] => { const validBirthdays = people.filter((element) => { const year = moment(element.birthday).year(); return year !== 0; }); const result = sortAndFilterBirthdays(validBirthdays, daysToGet); if (result.length > 1 && daysToGet <= 30) { return result; } const fallbackResult = validBirthdays .sort((firstEl, secondEl) => sortDate(firstEl.birthday, secondEl.birthday)) .filter((person) => { const currentYear = moment().year(); const date = moment(person.birthday, DATE_FORMAT).set('years', currentYear); return moment().diff(date, 'days') <= 0; }); return [...fallbackResult, ...validBirthdays].slice(0, 2); };
关键注意事项
- 泛型复用:
callMsGraphWithoutPagination改为泛型后,可适配不同MS Graph接口的返回类型,避免any带来的类型模糊。 - 类型断言:调用
data.json()时用as断言为对应接口类型,让TypeScript明确数据结构。 - 生日类型对齐:MS Graph返回的生日是字符串格式,需与
BirthdayPerson的birthday类型保持一致;若需Date类型,可在处理时转换(如new Date(birthdayJson.value))。 - 冗余代码清理:原代码中
setUsers([].concat(...processedData))属于冗余操作,直接赋值processedData即可。
内容的提问来源于stack exchange,提问作者Semedmar
相关产品推荐
相关产品推荐

