@@ -8,16 +8,28 @@ test("type inference", () => {
88 const recordWithEnumKeys = z . record ( z . enum ( [ "Tuna" , "Salmon" ] ) , z . string ( ) ) ;
99 type recordWithEnumKeys = z . infer < typeof recordWithEnumKeys > ;
1010
11- const recordWithLiteralKey = z . record ( z . literal ( [ "Tuna" , "Salmon" ] ) , z . string ( ) ) ;
11+ const recordWithLiteralKey = z . record ( z . literal ( [ "Tuna" , "Salmon" , 21 ] ) , z . string ( ) ) ;
1212 type recordWithLiteralKey = z . infer < typeof recordWithLiteralKey > ;
1313
14- const recordWithLiteralUnionKeys = z . record ( z . union ( [ z . literal ( "Tuna" ) , z . literal ( "Salmon" ) ] ) , z . string ( ) ) ;
14+ const recordWithLiteralUnionKeys = z . record (
15+ z . union ( [ z . literal ( "Tuna" ) , z . literal ( "Salmon" ) , z . literal ( 21 ) ] ) ,
16+ z . string ( )
17+ ) ;
1518 type recordWithLiteralUnionKeys = z . infer < typeof recordWithLiteralUnionKeys > ;
1619
20+ enum Enum {
21+ Tuna = 0 ,
22+ Salmon = "Shark" ,
23+ }
24+
25+ const recordWithTypescriptEnum = z . record ( z . enum ( Enum ) , z . string ( ) ) ;
26+ type recordWithTypescriptEnum = z . infer < typeof recordWithTypescriptEnum > ;
27+
1728 expectTypeOf < booleanRecord > ( ) . toEqualTypeOf < Record < string , boolean > > ( ) ;
1829 expectTypeOf < recordWithEnumKeys > ( ) . toEqualTypeOf < Record < "Tuna" | "Salmon" , string > > ( ) ;
19- expectTypeOf < recordWithLiteralKey > ( ) . toEqualTypeOf < Record < "Tuna" | "Salmon" , string > > ( ) ;
20- expectTypeOf < recordWithLiteralUnionKeys > ( ) . toEqualTypeOf < Record < "Tuna" | "Salmon" , string > > ( ) ;
30+ expectTypeOf < recordWithLiteralKey > ( ) . toEqualTypeOf < Record < "Tuna" | "Salmon" | 21 , string > > ( ) ;
31+ expectTypeOf < recordWithLiteralUnionKeys > ( ) . toEqualTypeOf < Record < "Tuna" | "Salmon" | 21 , string > > ( ) ;
32+ expectTypeOf < recordWithTypescriptEnum > ( ) . toEqualTypeOf < Record < Enum , string > > ( ) ;
2133} ) ;
2234
2335test ( "enum exhaustiveness" , ( ) => {
@@ -64,14 +76,76 @@ test("enum exhaustiveness", () => {
6476 ` ) ;
6577} ) ;
6678
79+ test ( "typescript enum exhaustiveness" , ( ) => {
80+ enum BigFish {
81+ Tuna = 0 ,
82+ Salmon = "Shark" ,
83+ }
84+
85+ const schema = z . record ( z . enum ( BigFish ) , z . string ( ) ) ;
86+ const value = {
87+ [ BigFish . Tuna ] : "asdf" ,
88+ [ BigFish . Salmon ] : "asdf" ,
89+ } ;
90+
91+ expect ( schema . parse ( value ) ) . toEqual ( value ) ;
92+
93+ expect ( schema . safeParse ( { [ BigFish . Tuna ] : "asdf" , [ BigFish . Salmon ] : "asdf" , Trout : "asdf" } ) ) . toMatchInlineSnapshot ( `
94+ {
95+ "error": [ZodError: [
96+ {
97+ "code": "unrecognized_keys",
98+ "keys": [
99+ "Trout"
100+ ],
101+ "path": [],
102+ "message": "Unrecognized key: \\"Trout\\""
103+ }
104+ ]],
105+ "success": false,
106+ }
107+ ` ) ;
108+ expect ( schema . safeParse ( { [ BigFish . Tuna ] : "asdf" } ) ) . toMatchInlineSnapshot ( `
109+ {
110+ "error": [ZodError: [
111+ {
112+ "expected": "string",
113+ "code": "invalid_type",
114+ "path": [
115+ "Shark"
116+ ],
117+ "message": "Invalid input: expected string, received undefined"
118+ }
119+ ]],
120+ "success": false,
121+ }
122+ ` ) ;
123+ expect ( schema . safeParse ( { [ BigFish . Salmon ] : "asdf" } ) ) . toMatchInlineSnapshot ( `
124+ {
125+ "error": [ZodError: [
126+ {
127+ "expected": "string",
128+ "code": "invalid_type",
129+ "path": [
130+ 0
131+ ],
132+ "message": "Invalid input: expected string, received undefined"
133+ }
134+ ]],
135+ "success": false,
136+ }
137+ ` ) ;
138+ } ) ;
139+
67140test ( "literal exhaustiveness" , ( ) => {
68- const schema = z . record ( z . literal ( [ "Tuna" , "Salmon" ] ) , z . string ( ) ) ;
141+ const schema = z . record ( z . literal ( [ "Tuna" , "Salmon" , 21 ] ) , z . string ( ) ) ;
69142 schema . parse ( {
70143 Tuna : "asdf" ,
71144 Salmon : "asdf" ,
145+ 21 : "asdf" ,
72146 } ) ;
73147
74- expect ( schema . safeParse ( { Tuna : "asdf" , Salmon : "asdf" , Trout : "asdf" } ) ) . toMatchInlineSnapshot ( `
148+ expect ( schema . safeParse ( { Tuna : "asdf" , Salmon : "asdf" , 21 : "asdf" , Trout : "asdf" } ) ) . toMatchInlineSnapshot ( `
75149 {
76150 "error": [ZodError: [
77151 {
@@ -96,6 +170,14 @@ test("literal exhaustiveness", () => {
96170 "Salmon"
97171 ],
98172 "message": "Invalid input: expected string, received undefined"
173+ },
174+ {
175+ "expected": "string",
176+ "code": "invalid_type",
177+ "path": [
178+ 21
179+ ],
180+ "message": "Invalid input: expected string, received undefined"
99181 }
100182 ]],
101183 "success": false,
@@ -143,13 +225,14 @@ test("pipe exhaustiveness", () => {
143225} ) ;
144226
145227test ( "union exhaustiveness" , ( ) => {
146- const schema = z . record ( z . union ( [ z . literal ( "Tuna" ) , z . literal ( "Salmon" ) ] ) , z . string ( ) ) ;
147- expect ( schema . parse ( { Tuna : "asdf" , Salmon : "asdf" } ) ) . toEqual ( {
228+ const schema = z . record ( z . union ( [ z . literal ( "Tuna" ) , z . literal ( "Salmon" ) , z . literal ( 21 ) ] ) , z . string ( ) ) ;
229+ expect ( schema . parse ( { Tuna : "asdf" , Salmon : "asdf" , 21 : "asdf" } ) ) . toEqual ( {
148230 Tuna : "asdf" ,
149231 Salmon : "asdf" ,
232+ 21 : "asdf" ,
150233 } ) ;
151234
152- expect ( schema . safeParse ( { Tuna : "asdf" , Salmon : "asdf" , Trout : "asdf" } ) ) . toMatchInlineSnapshot ( `
235+ expect ( schema . safeParse ( { Tuna : "asdf" , Salmon : "asdf" , 21 : "asdf" , Trout : "asdf" } ) ) . toMatchInlineSnapshot ( `
153236 {
154237 "error": [ZodError: [
155238 {
@@ -174,6 +257,14 @@ test("union exhaustiveness", () => {
174257 "Salmon"
175258 ],
176259 "message": "Invalid input: expected string, received undefined"
260+ },
261+ {
262+ "expected": "string",
263+ "code": "invalid_type",
264+ "path": [
265+ 21
266+ ],
267+ "message": "Invalid input: expected string, received undefined"
177268 }
178269 ]],
179270 "success": false,
0 commit comments