Skip to content

Commit 55812a8

Browse files
fixes
1 parent e96c5c3 commit 55812a8

File tree

4 files changed

+120
-31
lines changed

4 files changed

+120
-31
lines changed

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
# v3.0.3
2+
## Features
3+
- `Negate` now prevents nested negations — if the input is already negated, it returns as-is.
4+
- Added tests for `Inspect` and `Negate`.
5+
6+
## Fixes
7+
- Fixed `assert_is` (now `assert_tag`): swapped error message arguments and inverted logic for multi-type checks.
8+
- Fixed `table_flatten_with` setting a read property instead of a write property.
9+
- Fixed `table_map_values_deep` and `table_map_values_shallow` using read indexer removal instead of write indexer removal for write indexers.
10+
- Fixed `partial_core` checking `input.tag` instead of `value.tag` in its callback.
11+
- Fixed `Inspect` crashing on function types by passing them through instead of calling `:components()`.
12+
- Fixed `DeepRequired` docstring example not matching its input.
13+
14+
## Improvements
15+
- Replaced `assert_is_msg` and `assert_is` with a simpler `assert_tag(input, expected)` API that computes the tag internally.
16+
- Removed redundant `input_tag` parameter from `union_filter`, `intersection_filter`, `hashset_insert`, and `hashset_has_type`.
17+
- Simplified redundant `value_read == value_write` branching in `ValueOf`.
18+
119
# v3.0.2
220
## Features
321
- Added a `ValueOf` type function for getting all the value types of a table.

src/external.luau

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export type function kek()
2+
return types.never
3+
end
4+
5+
return nil

src/init.luau

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -370,10 +370,9 @@ end
370370
type function hashset_insert(
371371
hashset: typeof(types.newtable()),
372372
non_hashsettable: { type },
373-
input: type,
374-
input_tag: string
373+
input: type
375374
)
376-
if hashset_can_insert(input_tag) then
375+
if hashset_can_insert(input.tag) then
377376
hashset:setproperty(input, types.never)
378377

379378
else
@@ -384,10 +383,9 @@ end
384383
type function hashset_has_type(
385384
hashset: typeof(types.newtable()),
386385
non_hashsettable: { type },
387-
input: type,
388-
input_tag: string
386+
input: type
389387
)
390-
if hashset_can_insert(input_tag) then
388+
if hashset_can_insert(input.tag) then
391389
return if hashset:readproperty(input) then true else false
392390

393391
else
@@ -529,10 +527,10 @@ type function components_clean(
529527
end
530528
end
531529

532-
if hashset_has_type(hashset, non_hashsettable, component, component_tag) then
530+
if hashset_has_type(hashset, non_hashsettable, component) then
533531
input_len = table_value_swap_remove(input, input_len, idx)
534532
else
535-
hashset_insert(hashset, non_hashsettable, component, component_tag)
533+
hashset_insert(hashset, non_hashsettable, component)
536534
end
537535
end
538536

@@ -580,10 +578,10 @@ type function components_clean_unions_and_intersections(
580578
end
581579

582580
else
583-
if hashset_has_type(hashset, non_hashsettable, component, component_tag) then
581+
if hashset_has_type(hashset, non_hashsettable, component) then
584582
input_len = table_value_swap_remove(input, input_len, idx)
585583
else
586-
hashset_insert(hashset, non_hashsettable, component, component_tag)
584+
hashset_insert(hashset, non_hashsettable, component)
587585
end
588586
end
589587
end
@@ -623,8 +621,8 @@ type function union_from_components(input: { type })
623621
return if input_len == 0 then nil elseif input_len == 1 then input[1] else types.unionof(table.unpack(input))
624622
end
625623

626-
type function union_filter(input: type, input_tag: string, callback: (component: type) -> boolean)
627-
if input_tag == "union" then
624+
type function union_filter(input: type, callback: (component: type) -> boolean)
625+
if input.tag == "union" then
628626
return union_from_components(components_filter(input:components(), "union", union_from_components, callback))
629627
else
630628
return if callback(input) then nil else input
@@ -638,8 +636,8 @@ type function intersection_from_components(input: { type })
638636
return if input_len == 0 then nil elseif input_len == 1 then input[1] else types.intersectionof(table.unpack(input))
639637
end
640638

641-
type function intersection_filter(input: type, input_tag: string, callback: (component: type) -> boolean)
642-
if input_tag == "intersection" then
639+
type function intersection_filter(input: type, callback: (component: type) -> boolean)
640+
if input.tag == "intersection" then
643641
return intersection_from_components(components_filter(input:components(), "intersection", intersection_from_components, callback))
644642
else
645643
return if callback(input) then nil else input
@@ -1352,12 +1350,12 @@ export type function OmitUnion(input: type, to_omit: type)
13521350
if to_omit.tag == "union" then
13531351
local hashset, non_hashsettable = hashset_from_components(FlattenUnion(to_omit):components())
13541352

1355-
return union_filter(input, input_tag, function(component): boolean
1356-
return hashset_has_type(hashset, non_hashsettable, component, component.tag)
1353+
return union_filter(input, function(component): boolean
1354+
return hashset_has_type(hashset, non_hashsettable, component)
13571355
end) or types.never
13581356

13591357
else
1360-
return union_filter(input, input_tag, function(component: type)
1358+
return union_filter(input, function(component: type)
13611359
return component == to_omit
13621360
end) or types.never
13631361
end
@@ -1389,12 +1387,12 @@ export type function PickUnion(input: type, to_pick: type)
13891387
if to_pick.tag == "union" then
13901388
local hashset, non_hashsettable = hashset_from_components(FlattenUnion(to_pick):components())
13911389

1392-
return union_filter(input, input_tag, function(component): boolean
1393-
return not hashset_has_type(hashset, non_hashsettable, component, component.tag)
1390+
return union_filter(input, function(component): boolean
1391+
return not hashset_has_type(hashset, non_hashsettable, component)
13941392
end) or types.never
13951393

13961394
else
1397-
return union_filter(input, input_tag, function(component: type)
1395+
return union_filter(input, function(component: type)
13981396
return component ~= to_pick
13991397
end) or types.never
14001398
end
@@ -1483,12 +1481,12 @@ export type function OmitIntersection(input: type, to_omit: type)
14831481
if to_omit.tag == "union" then
14841482
local hashset, non_hashsettable = hashset_from_components(FlattenUnion(to_omit):components())
14851483

1486-
return intersection_filter(input, input_tag, function(component): boolean
1487-
return hashset_has_type(hashset, non_hashsettable, component, component.tag)
1484+
return intersection_filter(input, function(component): boolean
1485+
return hashset_has_type(hashset, non_hashsettable, component)
14881486
end) or types.never
14891487

14901488
else
1491-
return intersection_filter(input, input_tag, function(component: type)
1489+
return intersection_filter(input, function(component: type)
14921490
return component == to_omit
14931491
end) or types.never
14941492
end
@@ -1522,12 +1520,12 @@ export type function PickIntersection(input: type, to_pick: type)
15221520
if to_pick.tag == "union" then
15231521
local hashset, non_hashsettable = hashset_from_components(FlattenUnion(to_pick):components())
15241522

1525-
return intersection_filter(input, input_tag, function(component): boolean
1526-
return not hashset_has_type(hashset, non_hashsettable, component, component.tag)
1523+
return intersection_filter(input, function(component): boolean
1524+
return not hashset_has_type(hashset, non_hashsettable, component)
15271525
end) or types.never
15281526

15291527
else
1530-
return intersection_filter(input, input_tag, function(component: type)
1528+
return intersection_filter(input, function(component: type)
15311529
return component ~= to_pick
15321530
end) or types.never
15331531
end
@@ -1626,7 +1624,7 @@ export type function OmitTableByKeys(input: typeof(types.newtable()), to_omit: t
16261624
local hashset, non_hashsettable = hashset_from_components(FlattenUnion(to_omit):components())
16271625

16281626
return table_filter_by_keys(input, function(component: type)
1629-
return if hashset_has_type(hashset, non_hashsettable, component, component.tag) then true else false
1627+
return if hashset_has_type(hashset, non_hashsettable, component) then true else false
16301628
end)
16311629

16321630
else
@@ -1665,7 +1663,7 @@ export type function OmitTableByValues(input: typeof(types.newtable()), to_omit:
16651663
local hashset, non_hashsettable = hashset_from_components(FlattenUnion(to_omit):components())
16661664

16671665
return table_filter_by_values(input, function(component: type)
1668-
return if hashset_has_type(hashset, non_hashsettable, component, component.tag) then true else false
1666+
return if hashset_has_type(hashset, non_hashsettable, component) then true else false
16691667
end)
16701668

16711669
else
@@ -1704,7 +1702,7 @@ export type function PickTableByKeys(input: typeof(types.newtable()), to_pick: t
17041702
local hashset, non_hashsettable = hashset_from_components(FlattenUnion(to_pick):components())
17051703

17061704
return table_filter_by_keys(input, function(component: type)
1707-
return if not hashset_has_type(hashset, non_hashsettable, component, component.tag) then true else false
1705+
return if not hashset_has_type(hashset, non_hashsettable, component) then true else false
17081706
end)
17091707

17101708
else
@@ -1743,7 +1741,7 @@ export type function PickTableByValues(input: typeof(types.newtable()), to_pick:
17431741
local hashset, non_hashsettable = hashset_from_components(FlattenUnion(to_pick):components())
17441742

17451743
return table_filter_by_values(input, function(component: type)
1746-
return if not hashset_has_type(hashset, non_hashsettable, component, component.tag) then true else false
1744+
return if not hashset_has_type(hashset, non_hashsettable, component) then true else false
17471745
end)
17481746

17491747
else
@@ -2559,7 +2557,9 @@ end
25592557
-- type Result = ~string
25602558
]=]
25612559
export type function Negate(input: type)
2562-
return types.negationof(input)
2560+
return
2561+
if input.tag == "negation" then input
2562+
else types.negationof(input)
25632563
end
25642564
----------------------------------------------------------------------------------------
25652565

src/init.test.luau

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,3 +1301,69 @@ type Returns_TestD = t.Expect<
13011301
>
13021302
--------------------------------------------------------
13031303
-------------------------------------------------------------------------------------------------------
1304+
1305+
--> Miscellaneous -------------------------------------------------------------------------------------
1306+
-- Inspect ----------------------------------------
1307+
-- Test A: Inspects a union.
1308+
type Inspect_TestA = t.Expect<
1309+
t.Inspect<"hello" | "world">,
1310+
{ ["1"]: "hello", ["2"]: "world", kind: "union" }
1311+
>
1312+
1313+
-- Test B: Inspects an intersection.
1314+
type Inspect_TestB = t.Expect<
1315+
t.Inspect<"hello" & "world">,
1316+
{ ["1"]: "hello", ["2"]: "world", kind: "intersection" }
1317+
>
1318+
1319+
-- Test C: Inspects a negation.
1320+
type Inspect_TestC = t.Expect<
1321+
t.Inspect<t.Negate<string>>,
1322+
{ ["1"]: string, kind: "negation" }
1323+
>
1324+
1325+
-- Test D: Inspects a nested union inside an intersection.
1326+
type Inspect_TestD = t.Expect<
1327+
t.Inspect<"hello" & ("world" | "foo")>,
1328+
{ ["1"]: "hello", ["2"]: { ["1"]: "world", ["2"]: "foo", kind: "union" }, kind: "intersection" }
1329+
>
1330+
1331+
-- Test E: Inspects a primitive (passes through).
1332+
type Inspect_TestE = t.Expect<
1333+
t.Inspect<string>,
1334+
string
1335+
>
1336+
1337+
-- Test F: Inspects a table (passes through).
1338+
type Inspect_TestF = t.Expect<
1339+
t.Inspect<{ hello: "world" }>,
1340+
{ hello: "world" }
1341+
>
1342+
1343+
-- Test G: Inspects a function (passes through).
1344+
type Inspect_TestG = t.Expect<
1345+
t.Inspect<(string) -> number>,
1346+
(string) -> number
1347+
>
1348+
--------------------------------------------------------
1349+
1350+
-- Negate -----------------------------------------
1351+
-- Test A: Negates a primitive type.
1352+
type Negate_TestA = t.Expect<
1353+
t.Negate<string>,
1354+
t.Negate<string>
1355+
>
1356+
1357+
-- Test B: Negates a singleton type.
1358+
type Negate_TestB = t.Expect<
1359+
t.Negate<"hello">,
1360+
t.Negate<"hello">
1361+
>
1362+
1363+
-- Test C: Double negation is prevented (returns single negation).
1364+
type Negate_TestC = t.Expect<
1365+
t.Negate<t.Negate<string>>,
1366+
t.Negate<string>
1367+
>
1368+
--------------------------------------------------------
1369+
-------------------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)