1+ import { option as optionADT } from '../../../adts.js'
12import {
23 makeFunctionType ,
34 makeObjectType ,
4- makeOpaqueType ,
5+ makeOpaqueStringType ,
56 makeUnionType ,
6- matchTypeFormat ,
77 type FunctionType ,
88 type Type ,
99 type UnionType ,
@@ -16,77 +16,17 @@ export const nullType = makeUnionType('null', ['null'])
1616
1717export const boolean = makeUnionType ( 'boolean' , [ 'false' , 'true' ] )
1818
19- export const string = makeOpaqueType ( 'string' , {
20- isAssignableFrom : source =>
21- matchTypeFormat ( source , {
22- // functions cannot be assigned to `string`
23- function : _ => false ,
24- // `string` can't have object types assigned to it
25- object : _source => false ,
26- // the only opaque subtypes of `string` are `naturalNumber` and itself
27- opaque : source => source === string || source === naturalNumber ,
28- parameter : source =>
29- string . isAssignableFrom ( source . constraint . assignableTo ) ,
30- // `string` can have a union assigned to it if all of its members can be assigned to it
31- union : source => {
32- for ( const sourceMember of source . members ) {
33- if (
34- typeof sourceMember !== 'string' &&
35- ! string . isAssignableFrom ( sourceMember )
36- ) {
37- return false
38- }
39- }
40- return true
41- } ,
42- } ) ,
43- isAssignableTo : target =>
44- matchTypeFormat ( target , {
45- // `string` cannot be assigned to a function type
46- function : _ => false ,
47- // `string` can't be assigned to object types
48- object : _target => false ,
49- // `string` (currently) has no opaque supertypes (its only supertype is itself)
50- opaque : target => target === string ,
51- parameter : target => target . constraint . assignableTo === string ,
52- // `string` can only be assigned to a union type if `string` is one of its members
53- union : target => target . members . has ( string ) ,
54- } ) ,
19+ export const string = makeOpaqueStringType ( 'string' , {
20+ isAssignableFromLiteralType : ( _literalType : string ) => true ,
21+ nearestOpaqueAssignableFrom : ( ) => optionADT . makeSome ( naturalNumber ) ,
22+ nearestOpaqueAssignableTo : ( ) => optionADT . none ,
5523} )
5624
57- export const naturalNumber = makeOpaqueType ( 'natural_number' , {
58- isAssignableFrom : source =>
59- matchTypeFormat ( source , {
60- function : _ => false ,
61- object : _source => false ,
62- // `naturalNumber` (currently) has no opaque subtypes (its only subtype is itself)
63- opaque : source => source === naturalNumber ,
64- parameter : source =>
65- naturalNumber . isAssignableFrom ( source . constraint . assignableTo ) ,
66- // `naturalNumber` can have a union assigned to it if all of its members can be assigned to it
67- union : source => {
68- for ( const sourceMember of source . members ) {
69- if ( typeof sourceMember === 'string' ) {
70- if ( ! / (?: 0 | [ 1 - 9 ] (?: [ 0 - 9 ] ) * ) + / . test ( sourceMember ) ) {
71- return false
72- }
73- } else if ( ! naturalNumber . isAssignableFrom ( sourceMember ) ) {
74- return false
75- }
76- }
77- return true
78- } ,
79- } ) ,
80- isAssignableTo : target =>
81- matchTypeFormat ( target , {
82- function : _ => false ,
83- object : _target => false ,
84- opaque : target => target === naturalNumber || target === string ,
85- parameter : target => target . constraint . assignableTo === naturalNumber ,
86- // `naturalNumber` can only be assigned to a union type if `naturalNumber` is one of its members
87- union : target =>
88- target . members . has ( naturalNumber ) || target . members . has ( string ) ,
89- } ) ,
25+ export const naturalNumber = makeOpaqueStringType ( 'natural_number' , {
26+ isAssignableFromLiteralType : literalType =>
27+ / (?: 0 | [ 1 - 9 ] (?: [ 0 - 9 ] ) * ) + / . test ( literalType ) ,
28+ nearestOpaqueAssignableFrom : ( ) => optionADT . none ,
29+ nearestOpaqueAssignableTo : ( ) => optionADT . makeSome ( string ) ,
9030} )
9131
9232export const object = makeObjectType ( 'object' , { } )
0 commit comments