TypeScript中GraphQL自定义标量用Regex.test()报Apollo运行时错误求助
GraphQL自定义标量正则匹配报错解决
我在TypeScript中创建GraphQL自定义标量,实现了serialize、parseValue和parseLiteral函数,想用正则表达式校验传入的值,但使用if (value.test(yearMonthDayRegex)) {}作为判断条件时,触发了Apollo运行时错误:
TypeError: value.test is not a function at GraphQLScalarType.coerceType (/Users/mej/Documents/elastigraph/elastigraph/packages/core/src/lib/gqlScalarTypes.ts:30:20) at coerceInputValueImpl (/Users/mej/Documents/elastigraph/elastigraph/node_modules/.pnpm/graphql@16.6.0/node_modules/graphql/utilities/coerceInputValue.js:151:26) at coerceInputValueImpl (/Users/mej/Documents/elastigraph/elastigraph/node_modules/.pnpm/graphql@16.6.0/node_modules/graphql/utilities/coerceInputValue.js:117:34) at coerceInputValueImpl (/Users/mej/Documents/elastigraph/elastigraph/node_modules/.pnpm/graphql@16.6.0/node_modules/graphql/utilities/coerceInputValue.js:117:34) at coerceInputValue (/Users/mej/Documents/elastigraph/elastigraph/node_modules/.pnpm/graphql@16.6.0/node_modules/graphql/utilities/coerceInputValue.js:32:10) at coerceVariableValues (/Users/mej/Documents/elastigraph/elastigraph/node_modules/.pnpm/graphql@16.6.0/node_modules/graphql/execution/values.js:132:69) at getVariableValues (/Users/mej/Documents/elastigraph/elastigraph/node_modules/.pnpm/graphql@16.6.0/node_modules/graphql/execution/values.js:45:21) at buildExecutionContext (/Users/mej/Documents/elastigraph/elastigraph/node_modules/.pnpm/graphql@16.6.0/node_modules/graphql/execution/execute.js:280:63) at execute (/Users/mej/Documents/elastigraph/elastigraph/node_modules/.pnpm/graphql@16.6.0/node_modules/graphql/execution/execute.js:116:22) at /Users/mej/Documents/elastigraph/elastigraph/node_modules/.pnpm/@envelop+core@3.0.6/node_modules/@envelop/core/cjs/orchestrator.js:376:33
我的正则表达式为:const yearMonthDayRegex = /^d{4}-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])$/;
问题解决
正则调用顺序错误
报错的直接原因是搞反了正则方法的调用方式:test()是正则表达式对象的方法,需要用正则实例调用,传入要校验的字符串,正确写法是yearMonthDayRegex.test(value),而非value.test(yearMonthDayRegex)。正则表达式语法错误
正则里^d{4}中的d未转义,应写成^\d{4},否则会匹配字面量字符d,而非数字0-9。前置类型校验
在自定义标量的三个方法中,需先判断传入值的类型是否为字符串,避免非字符串类型触发额外错误。
修正后的示例代码
import { GraphQLScalarType, Kind } from 'graphql'; const yearMonthDayRegex = /^\d{4}-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])$/; export const DateScalar = new GraphQLScalarType({ name: 'Date', description: '仅接受YYYY-MM-DD格式的日期字符串', serialize(value: unknown) { if (typeof value === 'string' && yearMonthDayRegex.test(value)) { return value; } throw new Error('日期格式不符合要求,必须为YYYY-MM-DD'); }, parseValue(value: unknown) { if (typeof value === 'string' && yearMonthDayRegex.test(value)) { return value; } throw new Error('日期格式不符合要求,必须为YYYY-MM-DD'); }, parseLiteral(ast) { if (ast.kind === Kind.STRING && yearMonthDayRegex.test(ast.value)) { return ast.value; } throw new Error('日期格式不符合要求,必须为YYYY-MM-DD'); }, });
内容的提问来源于stack exchange,提问作者mojones101
相关产品推荐
相关产品推荐

