-
-
Notifications
You must be signed in to change notification settings - Fork 571
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
StructuredCloneable
/StructuredCloneableWeb
types
- Loading branch information
Kate Corcoran
committed
Jun 24, 2024
1 parent
e75dbe1
commit 4c117f3
Showing
6 changed files
with
455 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import type {TypedArray} from './typed-array'; | ||
|
||
type StructuredCloneableWebValue = | ||
| Blob | ||
| CryptoKey | ||
| DOMException | ||
| DOMMatrix | ||
| DOMMatrixReadOnly | ||
| DOMPoint | ||
| DOMPointReadOnly | ||
| DOMQuad | ||
| DOMRect | ||
| DOMRectReadOnly | ||
| File | ||
| FileList | ||
| FileSystemDirectoryHandle | ||
| FileSystemFileHandle | ||
| FileSystemHandle | ||
| ImageBitmap | ||
| ImageData | ||
| RTCCertificate | ||
| VideoFrame; | ||
// Missing types: | ||
// | AudioData | ||
// | CropTarget | ||
// | GPUCompilationInfo | ||
// | GPUCompilationMessage | ||
|
||
type StructuredCloneablePrimitive = | ||
| string | ||
| number | ||
| bigint | ||
| boolean | ||
| null | ||
| undefined | ||
| Boolean | ||
| Number | ||
| String; | ||
|
||
type StructuredCloneableData = | ||
| ArrayBuffer | ||
| DataView | ||
| Date | ||
| Error | ||
| RegExp | ||
| TypedArray; | ||
|
||
type StructuredCloneableCollection = | ||
| readonly StructuredCloneableWeb[] | ||
| {readonly [k: string]: StructuredCloneableWeb; readonly [k: number]: StructuredCloneableWeb} | ||
| ReadonlyMap<StructuredCloneableWeb, StructuredCloneableWeb> | ||
| ReadonlySet<StructuredCloneableWeb>; | ||
|
||
/** | ||
Matches a value that can be losslessly cloned using `structuredClone` (includes web types like `Blob` and `DOMRect`). | ||
Can be used to type values that you expect to pass to `structuredClone`. | ||
Note: | ||
- Custom error types will be cloned as the base `Error` type | ||
- This variant includes web-specific cloneable types (e.g. `Blob` and `DOMRect`) | ||
@see `StructuredCloneable` for a version that doesn't include web types | ||
@example | ||
``` | ||
import type {StructuredCloneableWeb} from 'type-fest'; | ||
class CustomClass {} | ||
// @ts-expect-error | ||
const error: StructuredCloneableWeb = { | ||
custom: new CustomClass(), | ||
}; | ||
structuredClone(error); | ||
//=> {custom: {}} | ||
const good: StructuredCloneableWeb = { | ||
blob: new Blob(["<div></div>"], { type: "text/html" }), | ||
date: new Date(), | ||
map: new Map<string, number>(), | ||
} | ||
good.map.set("key", 1) | ||
structuredClone(good); | ||
//=> {blob: Blob {size: 11, type: "text/html"}, date: Date(2022-10-17 22:22:35.920), map: Map {"key" -> 1}} | ||
``` | ||
@category Structured clone | ||
*/ | ||
export type StructuredCloneableWeb = StructuredCloneableWebValue | StructuredCloneablePrimitive | StructuredCloneableData | StructuredCloneableCollection; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import type {TypedArray} from './typed-array'; | ||
|
||
type StructuredCloneablePrimitive = | ||
| string | ||
| number | ||
| bigint | ||
| boolean | ||
| null | ||
| undefined | ||
| Boolean | ||
| Number | ||
| String; | ||
|
||
type StructuredCloneableData = | ||
| ArrayBuffer | ||
| DataView | ||
| Date | ||
| Error | ||
| RegExp | ||
| TypedArray; | ||
|
||
type StructuredCloneableCollection = | ||
| readonly StructuredCloneable[] | ||
| {readonly [k: string]: StructuredCloneable; readonly [k: number]: StructuredCloneable} | ||
| ReadonlyMap<StructuredCloneable, StructuredCloneable> | ||
| ReadonlySet<StructuredCloneable>; | ||
|
||
/** | ||
Matches a value that can be losslessly cloned using `structuredClone`. | ||
Can be used to type values that you expect to pass to `structuredClone`. | ||
Note: | ||
- Custom error types will be cloned as the base `Error` type | ||
- This type doesn't include the web-specific cloneable types (e.g. `Blob` and `DOMRect`) | ||
@see `StructuredCloneableWeb` for a version that includes the web-specific types | ||
@example | ||
``` | ||
import type {StructuredCloneable} from 'type-fest'; | ||
class CustomClass {} | ||
// @ts-expect-error | ||
const error: StructuredCloneable = { | ||
custom: new CustomClass(), | ||
}; | ||
structuredClone(error); | ||
//=> {custom: {}} | ||
const good: StructuredCloneable = { | ||
num: 3, | ||
date: new Date(), | ||
map: new Map<string, number>(), | ||
} | ||
good.map.set("key", 1) | ||
structuredClone(good); | ||
//=> {num: 3, date: Date(2022-10-17 22:22:35.920), map: Map {"key" -> 1}} | ||
``` | ||
@category Structured clone | ||
*/ | ||
export type StructuredCloneable = StructuredCloneablePrimitive | StructuredCloneableData | StructuredCloneableCollection; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
import {expectAssignable, expectNotAssignable} from 'tsd'; | ||
import type {StructuredCloneableWeb} from '..'; | ||
|
||
/* | ||
Source: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm | ||
# Supported types | ||
## JavaScript types | ||
- Array | ||
- ArrayBuffer | ||
- Boolean | ||
- DataView | ||
- Date | ||
- Error types (but see Error types below). | ||
- Map | ||
- Number | ||
- Object objects: but only plain objects (e.g. from object literals). | ||
- Primitive types, except symbol. | ||
- RegExp: but note that lastIndex is not preserved. | ||
- Set | ||
- String | ||
- TypedArray | ||
## Error types | ||
For Error types, the error name must be one of: Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError (or will be set to "Error"). | ||
## Web/API types | ||
- AudioData | ||
- Blob | ||
- CropTarget | ||
- CryptoKey | ||
- DOMException: browsers must serialize the properties name and message. Other attributes may also be serialized/cloned. | ||
- DOMMatrix | ||
- DOMMatrixReadOnly | ||
- DOMPoint | ||
- DOMPointReadOnly | ||
- DOMQuad | ||
- DOMRect | ||
- DOMRectReadOnly | ||
- File | ||
- FileList | ||
- FileSystemDirectoryHandle | ||
- FileSystemFileHandle | ||
- FileSystemHandle | ||
- GPUCompilationInfo | ||
- GPUCompilationMessage | ||
- ImageBitmap | ||
- ImageData | ||
- RTCCertificate | ||
- VideoFrame | ||
*/ | ||
|
||
// Date, Boolean, Number, String | ||
expectAssignable<StructuredCloneableWeb>(new Date()); | ||
declare const booleanWrapperObject: Boolean; | ||
expectAssignable<StructuredCloneableWeb>(booleanWrapperObject); | ||
declare const numberWrapperObject: Number; | ||
expectAssignable<StructuredCloneableWeb>(numberWrapperObject); | ||
declare const stringWrapperObject: String; | ||
expectAssignable<StructuredCloneableWeb>(stringWrapperObject); | ||
|
||
// Primitive types, except symbol. | ||
expectAssignable<StructuredCloneableWeb>(undefined); | ||
expectAssignable<StructuredCloneableWeb>(null); | ||
expectAssignable<StructuredCloneableWeb>(true); | ||
expectAssignable<StructuredCloneableWeb>(1); | ||
expectAssignable<StructuredCloneableWeb>(1n); | ||
expectAssignable<StructuredCloneableWeb>(''); | ||
declare const symbolValue: symbol; | ||
expectNotAssignable<StructuredCloneableWeb>(symbolValue); | ||
|
||
// RegExp: but note that lastIndex is not preserved. | ||
expectAssignable<StructuredCloneableWeb>(/foo/); | ||
|
||
// ArrayBuffer, DataView | ||
expectAssignable<StructuredCloneableWeb>(new ArrayBuffer(10)); | ||
expectAssignable<StructuredCloneableWeb>(new DataView(new ArrayBuffer(10))); | ||
|
||
// TypedArray | ||
expectAssignable<StructuredCloneableWeb>(new Int8Array(10)); | ||
expectAssignable<StructuredCloneableWeb>(new Uint8Array(10)); | ||
expectAssignable<StructuredCloneableWeb>(new Uint8ClampedArray(10)); | ||
expectAssignable<StructuredCloneableWeb>(new Int16Array(10)); | ||
expectAssignable<StructuredCloneableWeb>(new Uint16Array(10)); | ||
expectAssignable<StructuredCloneableWeb>(new Int32Array(10)); | ||
expectAssignable<StructuredCloneableWeb>(new Uint32Array(10)); | ||
expectAssignable<StructuredCloneableWeb>(new Float32Array(10)); | ||
expectAssignable<StructuredCloneableWeb>(new Float64Array(10)); | ||
expectAssignable<StructuredCloneableWeb>(new BigInt64Array(10)); | ||
expectAssignable<StructuredCloneableWeb>(new BigUint64Array(10)); | ||
|
||
// Error types | ||
declare const error: Error; | ||
expectAssignable<StructuredCloneableWeb>(error); | ||
declare const evalError: EvalError; | ||
expectAssignable<StructuredCloneableWeb>(evalError); | ||
declare const rangeError: RangeError; | ||
expectAssignable<StructuredCloneableWeb>(rangeError); | ||
declare const referenceError: ReferenceError; | ||
expectAssignable<StructuredCloneableWeb>(referenceError); | ||
declare const syntaxError: SyntaxError; | ||
expectAssignable<StructuredCloneableWeb>(syntaxError); | ||
declare const typeError: TypeError; | ||
expectAssignable<StructuredCloneableWeb>(typeError); | ||
declare const uriError: URIError; | ||
expectAssignable<StructuredCloneableWeb>(uriError); | ||
|
||
// Object objects: but only plain objects (e.g. from object literals). | ||
expectAssignable<StructuredCloneableWeb>({}); | ||
expectAssignable<StructuredCloneableWeb>({x: 10}); | ||
expectAssignable<StructuredCloneableWeb>({x: {y: 10}}); | ||
expectAssignable<StructuredCloneableWeb>({x: 10} as const); | ||
class CustomType {} | ||
expectNotAssignable<StructuredCloneableWeb>(new CustomType()); | ||
|
||
// Array | ||
expectAssignable<StructuredCloneableWeb>([]); | ||
expectAssignable<StructuredCloneableWeb>([1, 2, 3]); | ||
expectAssignable<StructuredCloneableWeb>([1, 2, 3] as const); | ||
expectAssignable<StructuredCloneableWeb>([[1, 2], [3, 4]]); | ||
expectAssignable<StructuredCloneableWeb>([{x: 1}, {x: 2}]); | ||
|
||
// Map | ||
expectAssignable<StructuredCloneableWeb>(new Map<string, Date>()); | ||
expectAssignable<StructuredCloneableWeb>(new Map<Date, string[]>()); | ||
expectAssignable<StructuredCloneableWeb>(new Map<Date, Map<string, number>>()); | ||
|
||
// Set | ||
expectAssignable<StructuredCloneableWeb>(new Set<number>()); | ||
expectAssignable<StructuredCloneableWeb>(new Set<string[]>()); | ||
expectAssignable<StructuredCloneableWeb>(new Set<Set<string>>()); | ||
|
||
// Web/API types | ||
declare const blob: Blob; | ||
expectAssignable<StructuredCloneableWeb>(blob); | ||
declare const cryptoKey: CryptoKey; | ||
expectAssignable<StructuredCloneableWeb>(cryptoKey); | ||
declare const domException: DOMException; | ||
expectAssignable<StructuredCloneableWeb>(domException); | ||
declare const domMatrix: DOMMatrix; | ||
expectAssignable<StructuredCloneableWeb>(domMatrix); | ||
declare const domMatrixReadOnly: DOMMatrixReadOnly; | ||
expectAssignable<StructuredCloneableWeb>(domMatrixReadOnly); | ||
declare const domPoint: DOMPoint; | ||
expectAssignable<StructuredCloneableWeb>(domPoint); | ||
declare const domPointReadOnly: DOMPointReadOnly; | ||
expectAssignable<StructuredCloneableWeb>(domPointReadOnly); | ||
declare const domQuad: DOMQuad; | ||
expectAssignable<StructuredCloneableWeb>(domQuad); | ||
declare const domRect: DOMRect; | ||
expectAssignable<StructuredCloneableWeb>(domRect); | ||
declare const domRectReadOnly: DOMRectReadOnly; | ||
expectAssignable<StructuredCloneableWeb>(domRectReadOnly); | ||
declare const file: File; | ||
expectAssignable<StructuredCloneableWeb>(file); | ||
declare const fileList: FileList; | ||
expectAssignable<StructuredCloneableWeb>(fileList); | ||
declare const fileSystemDirectoryHandle: FileSystemDirectoryHandle; | ||
expectAssignable<StructuredCloneableWeb>(fileSystemDirectoryHandle); | ||
declare const fileSystemFileHandle: FileSystemFileHandle; | ||
expectAssignable<StructuredCloneableWeb>(fileSystemFileHandle); | ||
declare const fileSystemHandle: FileSystemHandle; | ||
expectAssignable<StructuredCloneableWeb>(fileSystemHandle); | ||
declare const imageBitmap: ImageBitmap; | ||
expectAssignable<StructuredCloneableWeb>(imageBitmap); | ||
declare const imageData: ImageData; | ||
expectAssignable<StructuredCloneableWeb>(imageData); | ||
declare const rtcCertificate: RTCCertificate; | ||
expectAssignable<StructuredCloneableWeb>(rtcCertificate); | ||
declare const videoFrame: VideoFrame; | ||
expectAssignable<StructuredCloneableWeb>(videoFrame); | ||
|
||
// Missing types: | ||
|
||
/* | ||
declare const audioData: AudioData; | ||
expectAssignable<StructuredCloneableWeb>(audioData); | ||
declare const cropTarget: CropTarget; | ||
expectAssignable<StructuredCloneableWeb>(cropTarget); | ||
declare const gpuCompilationInfo: GPUCompilationInfo; | ||
expectAssignable<StructuredCloneableWeb>(gpuCompilationInfo); | ||
declare const gpuCompilationMessage: GPUCompilationMessage; | ||
expectAssignable<StructuredCloneableWeb>(gpuCompilationMessage); | ||
*/ |
Oops, something went wrong.