diff --git a/example/legacy/index.ts b/example/legacy/index.ts new file mode 100644 index 0000000..79f1793 --- /dev/null +++ b/example/legacy/index.ts @@ -0,0 +1,29 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox/legacy + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +export * from './intersect' \ No newline at end of file diff --git a/example/legacy/intersect.ts b/example/legacy/intersect.ts new file mode 100644 index 0000000..d2fbd95 --- /dev/null +++ b/example/legacy/intersect.ts @@ -0,0 +1,66 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox/legacy + +The MIT License (MIT) + +Copyright (c) 2017-2023 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +import { TObject, ObjectOptions, Modifier, Kind, TSchema, Static } from '@sinclair/typebox' + +export type IntersectLegacyReduce = T extends [infer A, ...infer B] ? IntersectLegacyReduce : I extends object ? I : {} +export type IntersectLegacyEvaluate = { [K in keyof T]: T[K] extends TSchema ? Static : never } +export type IntersectLegacyProperties = { + [K in keyof T]: T[K] extends TObject ? P : {} +} +export interface TIntersectLegacy extends TObject { + static: IntersectLegacyReduce> + properties: IntersectLegacyReduce> +} + +/** `Legacy` Creates a legacy intersect type. */ +export function IntersectLegacy(objects: [...T], options: ObjectOptions = {}): TIntersectLegacy { + const isOptional = (schema: TSchema) => (schema[Modifier] && schema[Modifier] === 'Optional') || schema[Modifier] === 'ReadonlyOptional' + const [required, optional] = [new Set(), new Set()] + for (const object of objects) { + for (const [key, schema] of Object.entries(object.properties)) { + if (isOptional(schema)) optional.add(key) + } + } + for (const object of objects) { + for (const key of Object.keys(object.properties)) { + if (!optional.has(key)) required.add(key) + } + } + const properties = {} as Record + for (const object of objects) { + for (const [key, schema] of Object.entries(object.properties)) { + properties[key] = properties[key] === undefined ? schema : { [Kind]: 'Union', anyOf: [properties[key], { ...schema }] } + } + } + if (required.size > 0) { + return { ...options, [Kind]: 'Object', type: 'object', properties, required: [...required] } as any + } else { + return { ...options, [Kind]: 'Object', type: 'object', properties } as any + } +}