如何在Node.js/TypeScript中为Google Places Text Search(New)正确添加类型?
关于Node.js+TypeScript集成Google Places Text Search(New) API的问题解答
1. 手动定义请求与响应类型
你可以根据Google Places Text Search API的官方结构,手动编写TypeScript类型,确保请求和响应的类型安全:
请求参数类型
定义请求Payload的类型,对应API的SearchTextRequest结构(可根据需求添加可选参数):
// 请求参数类型 interface SearchTextRequest { textQuery: string; // 可选参数示例 locationBias?: { circle?: { center: { latitude: number; longitude: number }; radius: number; }; }; languageCode?: string; maxResultCount?: number; }
响应数据类型
拆分响应的子类型,再组合成完整的响应结构:
// 地点坐标类型 interface LatLng { latitude: number; longitude: number; } // 地点核心信息类型 interface Place { name: string; id: string; formattedAddress?: string; location?: LatLng; rating?: number; userRatingCount?: number; // 其他需要的字段可参考API文档补充 } // 整体响应类型 interface SearchTextResponse { places: Place[]; nextPageToken?: string; }
改造原有函数
将类型应用到代码中,明确参数和返回值的类型:
import axios from 'axios'; const apiKey = process.env.GOOGLE_PLACES_API_KEY; // 建议用环境变量管理密钥 const endpoint = `https://places.googleapis.com/v1/places:searchText`; async function searchPlaces(query: string): Promise<SearchTextResponse> { const payload: SearchTextRequest = { textQuery: query }; const response = await axios.post<SearchTextResponse>(endpoint, payload, { headers: { 'Content-Type': 'application/json', 'X-Goog-Api-Key': apiKey, 'X-Goog-FieldMask': 'places.name,places.id,places.formattedAddress', // 建议指定需要的字段,替代* }, }); return response.data; }
2. 现成的TypeScript工具包
有几个成熟工具可以省去手动写类型的麻烦:
- @googlemaps/google-maps-services-js:Google官方维护的服务端Node.js库,自带完整的TypeScript类型定义,封装了所有Places API的调用逻辑,无需自行处理请求头和参数格式。
使用示例:import { Client } from '@googlemaps/google-maps-services-js'; const client = new Client({}); const apiKey = process.env.GOOGLE_PLACES_API_KEY; async function searchPlaces(query: string) { const response = await client.textSearch({ params: { query, key: apiKey, // 其他可选参数如language、radius等 }, }); // response.data自带完整类型提示 return response.data; } - openapi-typescript:Google Places API提供OpenAPI规范,可使用该工具自动生成类型定义文件,直接在代码中引用。
3. 服务端调用方式的有效性
这种服务端调用方式完全有效,官方虽多展示客户端示例,但服务端调用是被支持的,注意以下细节:
- 密钥安全:服务端存储API密钥不会暴露给前端,比客户端调用更安全,务必用环境变量管理密钥,不要硬编码到代码中。
- 请求优化:
X-Goog-FieldMask不要用通配符*,指定具体需要的字段可以减少返回数据量,提升请求性能。 - 错误处理:添加异常捕获逻辑,处理API返回的错误(如密钥无效、请求超限等):
async function searchPlaces(query: string): Promise<SearchTextResponse> { try { const payload: SearchTextRequest = { textQuery: query }; const response = await axios.post<SearchTextResponse>(endpoint, payload, { headers: { 'Content-Type': 'application/json', 'X-Goog-Api-Key': apiKey, 'X-Goog-FieldMask': 'places.name,places.id', }, }); return response.data; } catch (error) { if (axios.isAxiosError(error)) { console.error('Places API请求失败:', error.response?.data); throw new Error(`搜索失败: ${error.response?.data.error.message}`); } throw error; } }
内容的提问来源于stack exchange,提问作者BSimpson
相关产品推荐
相关产品推荐

