如何让Supabase RPC生成的TS类型中current_status支持空值?
解决Supabase RPC函数生成TS类型时可空字段的问题
我创建了一个Supabase RPC函数get_bananas,使用npx supabase gen types命令生成TypeScript类型定义时遇到问题:由于函数中使用LEFT JOIN关联表,返回的current_status字段可能为null,但生成的TS类型中该字段被定义为非空的枚举类型。我希望将其修改为可空类型(null | Database['public']['Enums']['status_type_enum'])。
生成的TS类型
get_bananas: { Args: { _limit?: number; _offset?: number; }; Returns: { id: string; text: string; current_status: Database['public']['Enums']['status_type_enum']; // 期望改成:current_status: null | Database['public']['Enums']['status_type_enum']; }[]; };
RPC函数原代码
CREATE TYPE status_type_enum AS ENUM ('rotten', 'ripe'); CREATE FUNCTION get_bananas( _limit INT DEFAULT NULL, _offset INT DEFAULT 0 ) RETURNS TABLE ( id UUID, text TEXT, current_status status_type_enum // 如何让TS识别这个字段可空?🙏 ) LANGUAGE plpgsql AS $$ BEGIN RETURN QUERY SELECT b.id, b.text, s.status_type AS current_status FROM bananas b LEFT JOIN statuses s ON b.id = s.banana_id AND s.user_id = auth.uid() LIMIT _limit OFFSET _offset; END; $$;
解决方案
1. 修改SQL函数的返回表定义
在RETURNS TABLE里的current_status字段类型后添加NULL修饰符,明确告诉PostgreSQL该字段允许为空:
CREATE TYPE status_type_enum AS ENUM ('rotten', 'ripe'); CREATE FUNCTION get_bananas( _limit INT DEFAULT NULL, _offset INT DEFAULT 0 ) RETURNS TABLE ( id UUID, text TEXT, current_status status_type_enum NULL -- 添加NULL标记可空 ) LANGUAGE plpgsql AS $$ BEGIN RETURN QUERY SELECT b.id, b.text, s.status_type AS current_status FROM bananas b LEFT JOIN statuses s ON b.id = s.banana_id AND s.user_id = auth.uid() LIMIT _limit OFFSET _offset; END; $$;
2. 重新生成TS类型
运行你原来的类型生成命令(示例如下),重新生成的TS类型中current_status会自动变为可空枚举类型:
npx supabase gen types typescript --project-id <你的项目ID> --schema public > types/supabase.ts
修改后生成的TS类型:
get_bananas: { Args: { _limit?: number; _offset?: number; }; Returns: { id: string; text: string; current_status: null | Database['public']['Enums']['status_type_enum']; }[]; };
原理说明
Supabase的类型生成工具依赖PostgreSQL的元数据生成TS类型,只有在SQL层面明确标记字段可空,工具才能正确识别并生成对应的可空TS类型。因为LEFT JOIN可能返回null结果,所以必须在RETURNS TABLE的字段定义中添加NULL修饰符。
内容的提问来源于stack exchange,提问作者Potato
相关产品推荐
相关产品推荐

