定义断言用户非空的TS函数时遇TS1225错误,求解决方案
解决TS1225错误并实现上下文断言逻辑
错误原因
你遇到的TS1225: Cannot find parameter User错误,是因为断言函数语法里的asserts User is DatabaseUser把User当成了函数的值参数,但它其实是类型的泛型参数,TypeScript无法将类型参数识别为断言目标的变量,因此报错。
可行解决方案
我们可以调整断言逻辑,让authenticationRequired断言当前上下文(this)的类型为已登录状态的GraphQLContext<DatabaseUser>,这样调用方法后TypeScript会自动收窄上下文类型,实现你期望的类型推导。
1. 修改类型定义
type DatabaseUser = { id: string; name: string; } export type GraphQLContext<User extends DatabaseUser | null> = { user: User; signedIn: User extends DatabaseUser ? true : false; // 修改为断言this的类型 authenticationRequired: () => asserts this is GraphQLContext<DatabaseUser>; };
2. 实现上下文创建函数
function createContext<User extends DatabaseUser | null>(user: User): GraphQLContext<User> { return { user, signedIn: (user !== null) as User extends DatabaseUser ? true : false, authenticationRequired() { if (!this.user) { throw new Error("Authentication required"); } } }; }
3. 使用示例
调用authenticationRequired后,TypeScript会自动识别上下文的user为非空的DatabaseUser:
// 未登录上下文 const unauthedCtx = createContext(null); // 运行时会抛出错误,但编译时调用后会收窄类型 unauthedCtx.authenticationRequired(); console.log(unauthedCtx.user.name); // TypeScript不再报错,因为已断言user非空 // 已登录上下文 const authedCtx = createContext({ id: "1", name: "Alice" }); authedCtx.authenticationRequired(); console.log(authedCtx.user.name); // 正常访问,无类型错误
原理说明
通过断言this is GraphQLContext<DatabaseUser>,我们告诉TypeScript:调用authenticationRequired后,当前上下文的类型必定是已登录状态(User为DatabaseUser而非null)。TypeScript会基于这个断言,自动收窄上下文的类型,从而允许直接访问user.name这类属性。
内容的提问来源于stack exchange,提问作者Abir Taheer
相关产品推荐
相关产品推荐

