Blobのコンストラクタ引数にTypedArrayとか直接使わないでください

# TD; LR;
JavaScriptのBlobのコンストラクラの第一引数について、仕様を理解せずつかうと上手くいかないこともある

# Blob第一引数
MDNの記述では
```text
array
反復可能オブジェクト、例えば Array などです。その中身が ArrayBuffer、
TypedArray、DataView、Blob、文字列などのオブジェクト、
またはそのようなオブジェクトの何れかが混合したもので、それが Blob の中に入れられます。
ここで文字列は UTF-8 で符号化されたものであり、 JavaScript におけるふつうの 
UTF-16 の文字列ではありません。
```
https://developer.mozilla.org/ja/docs/Web/API/Blob/Blob

本来は
```javascript
const binary = new Uint8Array([11,22,33,44])
const blob = new Blob([binary]) // binaryが配列の中にある
```
と書いてほしいという記述なんですが、そもそもTypedArray(Uint8Arrayとかのこと)も反復可能オブジェクトですよね?そのままいれてはいけないんですか?って話です

```javascript
const createLink = (blob:any, title:string, download:string) => {
    // @ts-ignore
    const url = URL.createObjectURL(blob)
    const anchor = document.createElement('a')
    anchor.innerHTML = title
    anchor.href = url
    anchor.download = download
    anchor.style.display = 'block'
    return anchor
}
const main = async() => {
    const numbers = [11,22,33,44,-100]
    const binary = new Int8Array(numbers)

    // Arrayの要素としてUint8Arrayをいれている
    const blob = new Blob([binary])

    // Uint8Arrayをそのまま第一引数にしている
    // @ts-ignore
    const blob2 = new Blob(binary)
    // raw arrayを第一引数にしている
    // @ts-ignore
    const blobNumbers = new Blob(numbers)
    
    const anchor0 = createLink(blob, 'blob correct', 'typedarray.raw')
    const anchor1 = createLink(blob2, 'blob incorrect', 'typedarray-wrong.raw')
    // @ts-ignore
    const anchor2 = createLink(blobNumbers, 'array', 'blobarray.raw')

    document.body.appendChild(anchor0)
    document.body.appendChild(anchor1)
    document.body.appendChild(anchor2)
}
document.addEventListener("DOMContentLoaded", (event:unknown) => {
    main()
})

```
ダウンロードリンクを3つだしているわけですが、
- Arrayの要素にTypedArrayをいれたパターン
- Arrayの要素にせず直接Int8Arrayをつめたパターン
- 数値のArrayをつめたパターン
です
おのおのダウンロードすると以下のような「バイナリファイル」が保存されます

1つめ
```
0B16212C 9C
```
2つめ
```
31313232 33333434 2D313030
```

3つめ
```
31313232 33333434 2D313030
```

2つめと3つめはテキストエディタで開くと以下のとおりになります
```
11223344-100
```

# なにがおきているのか?
Blobのコンストラクタの定義はECMA-262で定義されるWebIDLによれば以下の通り記述されるものです
```
[Constructor(optional sequence<BlobPart> blobParts,
             optional BlobPropertyBag options),
 Exposed=(Window,Worker), Serializable]
interface Blob {
...
typedef (BufferSource or Blob or USVString) BlobPart;
...
```
https://github.com/microsoft/TypeScript-DOM-lib-generator/blob/e2a2072d804999180f45c43f102d2ee604fade65/inputfiles/idl/File.widl
sequenceは型を取れるリストですが、こちらは長いので
https://triple-underscore.github.io/infra-ja.html#list
とかを読むといいです
そしてsequenceに取る型はBlobPartです
BlobPartはBlob,USVString,BufferSourceのいずれかです
ここで
```
type BufferSource = ArrayBufferView | ArrayBuffer;
```
ArrayBufferViewは以下を参照してください
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/isView


結局なにかというと文字列(USVStringは16bit表現の文字列)かArrayBuffer(View)か、Blobの配列がBlobのコンストラクタの第一引数でとることのできる型になり、ArrayBufferはそのままバイナリを、そうでないものは文字列表現に変換されBlobにおさめられるることとなります

ですので[TypedArray]で生成されたBlobではバイナリが、TypedArrayを直接指定するとSerializeされた文字列が保存されます
つまり[11,22,33,44,-100]はバリナリではなく文字列として11223344-100としてBlobに保存されることになります

# Blobの第一引数がsequenceなのはなぜだろう?
複合的なデータを構築するためでしょう。テキストであれ、バイナリであれ、順列に構成していくことで多様なデータ形式に対応するためにこのような仕様になってると思います(根拠はない)

# typescriptでは?
WebIDLから生成された制約が有効になるためサンプルのように無効化しない限りエラーになります
これを無視しない限り、変な問題には遭遇しないことが期待されます
第一引数はBlobPart[]になります(詳細は上述の通りです)

# まとめ
Blobの第一引数についての謎をおいかけました
この内容を理解した上で、最初のMDNの記述を読むと「正しく」理解できると思います

# 雑感
調べると言語/API仕様のお気持みたいなものがわかる気がする