对象类型

在 JavaScript 中,我们分组和传递数据的基本方式是通过对象。在 TypeScript 中,我们通过对象类型来表示它们。

正如我们所见,它们可以是匿名的:

function greet(person: { name: string; age: number }) {
  //                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  return "Hello " + person.name;
}

或者它们可以通过使用任何一个接口来命名

interface Person {
  //      ^^^^^^
  name: string;
  age: number;
}

function greet(person: Person) {
  return "Hello " + person.name;
}

或类型别名。

type Person = {
  // ^^^^^^
  name: string;
  age: number;
};

function greet(person: Person) {
  return "Hello " + person.name;
}

在上述所有三个示例中,我们编写的函数接受包含属性 name(必须是 string)和 age(必须是 number)的对象。

属性修饰符

M5VfOJ9gQ5zlGI/8/zaGPZPJTD3RClDLelvAXso/99UrDoyKFmZKFX9+DAiGOKcjVPhJfQoQWSZLJwDT3zRyO/LK8d/BvRHTZAnQizy6IbQsIsCtZan/W9ALfqxLF+omYw61NszdRnzkm0DOPLQer7BQlvaNV7V/e+H3pnRfYLI=

可选属性

0sFJWfhHkAbKJsOELGEvVlk9aghFh7dcb/DVUETvcUOPgsTIGoCjmxpNLcpvyEzoD6Vj7qPohMOjm2LGdg/CZY+qkjp/rJJUDS3zKh56Al01RLaRSmsyJlkffDK4eMKk5W6or0n5rKZuCVZ5MeZrC7qpf90uh/62JYIpDElDGLcrGFkwt+LSBPkLLetpZ5KTRcbfzftJNKsKfeehsUwpeTYliOe5xU77Y9PX0qZ9EDnvSRlypsz0QXZ/XHm1MWBR9vqffhRCm/+Mud8P/uoZTg==

interface Shape {}
declare function getShape(): Shape;

interface PaintOptions {
  shape: Shape;
  xPos?: number;
  //  ^
  yPos?: number;
  //  ^
}

function paintShape(opts: PaintOptions) {
  // ...
}

const shape = getShape();
paintShape({ shape });
paintShape({ shape, xPos: 100 });
paintShape({ shape, yPos: 100 });
paintShape({ shape, xPos: 100, yPos: 100 });

QXPPeMjUghWUk+ehQOMfi8RvADox3Jd7pwZlvyqguL3oYBHglBMcs3HU6EugSLEeVqld/dr0gH8yxM0ZitGNnXfTkzANn0gT+qK86JRvr6asZrq/57pLgrwdEaF57DdBUlq+S5HZPhlZ7ZAbh7GQ4xWJDcRDYtnCUEyiQW6pKdCn/PlACWK6RX+p9TA8IuXztzN/2fzoqduqWwhWEokB9aPbCt2nV5yXOH+UE1VQwJZfJvMSRkbF1lxTh3rvRnRqy4jGZVW8uIGw9VqIkqT7TUo/49llT8/Bx2Zd9aC3xMwMyS6DtucjUCYh5QK69XRWRi3/TuC4dq2wc4aF+s357Dq4K6qoZFkFxYyoMU3/WGZ2ADFcOk4ujVCivmLom78wxbx1yCmUQ6rjfkslysrYjn38kXkZzQpz4UiqKojgnFM=

SWKWc6oPEKN21aRL47RrntC6wam7TXp/TKzWitzb/XJyno9T4xd7Z24fVb6UcjZ4GlZsSVfP8sH5y8VGZWyeW5Ves9GLC3ckBRlIBYhPI1loQE26hsa0tXBZCncxDHIk4/bCuCVPviN0t+qt47rg20if/Ey0RvANqk779MlVoAaPH8rJNZZq7KAYJtc6hBL1FbeM3ES9xWxsyp1AiNXF5gu4p9MEupHTHIDCWqA3Cqgs1QF/25EF537Xgy+6xRNfYR2s+UHKo8qEGLtZrBBpJ8AGf5MbKZ43DgHtrmNEVTyIpgWyQnzEtBoHJAVK6hG0

interface Shape {}
declare function getShape(): Shape;

interface PaintOptions {
  shape: Shape;
  xPos?: number;
  yPos?: number;
}

function paintShape(opts: PaintOptions) {
  let xPos = opts.xPos;
  let yPos = opts.yPos;
  // ...
}

L3ZdRPtWJdOSKBxaPbeeuqVX/syOECJXJzsLzhtCJWdSvCkWmBHtckVdZMxE6P3yx9tyV7RH/qSST6Ba1JXBSwr1gP3gBQYK7JxsmRcqYo6SSwLcpeImH9BeJvsNYza3RU+ZBa+Ido2ve12ZCm/OP2VunJ3eQoVrUFNibFxh0icpCNVXZbAdtA69bE1XilBKeEor0TEe6tkNV2cHu2dipVLbgpiqVZJqG7Cotxy8NYKKT9GfL5HWm2TcOnH6D6Fs

interface Shape {}
declare function getShape(): Shape;

interface PaintOptions {
  shape: Shape;
  xPos?: number;
  yPos?: number;
}

function paintShape(opts: PaintOptions) {
  let xPos = opts.xPos === undefined ? 0 : opts.xPos;
  let yPos = opts.yPos === undefined ? 0 : opts.yPos;
  // ...
}

OiczrAsPOU4WV9AJ20ZERny7V/Qn9b1LoaInsFsYbZcB9fCOY2u+ziCli1YoRuyHAWGjhl6oWmSfygm37K5Ww2ivj+m7TRYliSH8U4LnoxnVn5tMSp079HcLfKWTNtwCaEAVBO0iT6aNp+gcUKfEt046mEuLI8sXaOt4lqfcYMo=

interface Shape {}
declare function getShape(): Shape;

interface PaintOptions {
  shape: Shape;
  xPos?: number;
  yPos?: number;
}

function paintShape({ shape, xPos = 0, yPos = 0 }: PaintOptions) {
  console.log("x coordinate at", xPos);
  console.log("y coordinate at", yPos);
  // ...
}

mxD5E3K54NdyWvm7/HGJOKwZNmI6dUoyXb0gc38MeI6fq+Cxv0/BS8b1W8sCBoCFa1kKnMMoFKr/+s99//IWL0Edtt877CrULeiSCyjdO3djPqpu+ueuVCe8XCEOF7a3UOBF2bc1Iy7byarraKPJgx3357B3jJlSa05UDD4GVNpgqRPCRXys+bZ65A7T2AWefMnKzW4AiCB3cxoM19CcbROA3BnWzDS1XTpJ5hi/6n1emBRqR5qHQhMZ+D0KFv999jtRrl2iVIL+FXYEmgAlNJL4LOD0gqxIjhdX7mgPiAi2JR6An4mXo/zw0Njhzd6qh+b4AHEcYLDpYybsUwR0SYTuBzqw+7EQAYX0iK9mpKObFzTsJSrVvESUBP2IX6GPejM2R3zjqcgr6iJcVYkgdkRpr8WXW+JdxDzAufJX/KuNVe/41jN2SwwY9aECoHo4R4aQku/bidMScYidq371Zd+AgOsRTCBaqIOHhthsME7Kkr4+R4FgrFVk6s7nk6v2IVnSYciCBeEhjbZM2dXWtTSZee5ZQ0IhF/F+pvtpdBj+GstdtrePrQ7VJLmnL6LD

wxv55pzAQInrj/7ZrTgIrVr7xWf8J0IVwubtS/874bsLt67egyHox1dsRX0vrSvJwMr45jYOjmAFrzDvQ1XBtYM8zKxMxN6iTEyP2sBOniFYL64t/qER5/RvfoOS+MMUw8VqJDZsIkS7JWwWkRgEmP04I+gtxpX/O/4QaOZigRlS2Tkhaq41lkpD6LqwbXF8/hQsN8ECI5TrvjL50sRA6w==

interface Shape {}
declare function render(x: unknown);
function draw({ shape: Shape, xPos: number = 100 /*...*/ }) {
  render(shape);
  render(xPos);
}

EAV76YDL8TBvqktD2fvNfZZy57zdmgjF3PwQZcGmI4sOxj0cNJ1H4m6V4kp+LT2wMxFQEHnKWQoj6SLuVQIbW640LZdf1T1Ers5Ym5LOOkzr16XsBY8xq9oQpElGISq8fvjdJDVaoMdQSs1N5WmOI43wEl1XCI7mkt+lTQKRfIDzEJ0OoM+Ht7krd9uLiPV5HO2ZguWVveYI7aXORsdDaRT0avQXkJDqyY4izmmEAG0g8V2sG0YNoENVvMAqFO5U+XsiURboPovIazskryUytFmvrSTK/MIgKnXaRYAlQpA1AF6Tz2yykyd//iB0C66cDiVL4LjSZTrdZ/ubXSm41JaDpPe0Tl2uW8JizAdqu8tetMyswAts6EwLSOgqmlY4OQhYKKPbfs32O2C11IKR7g==

XzTlahr6SO0mJUI6NaSoPtblAN6+kly1xbxDsE/w0hCOmfIVIMQJjaknL1KDA0VCh8jzabw4btaRLwywA+FSz44QZCJSi9v4NlM/owkheZojLZKLy/3+VNqk2YR3xihZImSOoCXDoRDc+HUjbOhh/5xdtST4AuhtvfRyVWdzHpY=

readonly 属性

Fcd4JtA/LA60DJEnznZoj450a+A/GR+xVaO7Mqi+FLUuT8FzxF+FjO0m5EzVypDmL5tZ/HN0OyNZBFjWT1HCk10sxSBZkSzS1AYelcmLf43wEQOAwR96sGyOqqu7uOLVN7QEImuhBIPl6vu7/2JBO921ZwatkHIFLZourvoqiL9QTfbFP9pOzGFIMkjo9QyeLEDV+RUG8+bGKjXflloDy9Op6rYTT6pjGU056AYD1I1UuzQsnTshW4d70ZDcTuj6I/tKtgPcx5sD8YPhTbdRVQ==

interface SomeType {
  readonly prop: string;
}

function doSomething(obj: SomeType) {
  // We can read from 'obj.prop'.
  console.log(`prop has the value '${obj.prop}'.`);

  // But we can't re-assign it.
  obj.prop = "hello";
}

iqcJ3N593O2EwfpqEu/zh+XNk9F2RmKYPSzT5IsjZGqHP6z45ZoLw/CmzQlE4uQX9k2a2LlTMj2HPiQKksagGXqVTVDCFedSLDJfCURRtSsegvL/KxGDNchNnq0LVqIV1wyTlnRSo3rnIACguUWXfiZ5E16KbGYL+54mxs8HE/mmRxuRIQUU6nbwjYAT6VlGacxg+tGp7Z8/GyLPENCNuhLdYkVGoY6TYCF5Lp/cuDmgYgjTOdgMNQXFQym3SsUuP5xTuMGVxQCph85gXHbAwA==

interface Home {
  readonly resident: { name: string; age: number };
}

function visitForBirthday(home: Home) {
  // We can read and update properties from 'home.resident'.
  console.log(`Happy birthday ${home.resident.name}!`);
  home.resident.age++;
}

function evict(home: Home) {
  // But we can't write to the 'resident' property itself on a 'Home'.
  home.resident = {
    name: "Victor the Evictor",
    age: 42,
  };
}

8EbpZuyqC5/5xad+9skxWdm7IdgGYdMb1NPrlCMnNjkTplPPrfFKyQYjJwC8MtOqCXWKYepheOmz5DxAyVfj4iDGvZqb/kulDahrTX2Kx3tuoZbd6pZbL2JSLouz7wiS8eHKfnTHd8Jr5JpjipI6tbWGYc4UIePBkrSHL6NuAXJVGp+HNGPNdi1naNZpHgjttb+VNxtVVCCMFUvytefqiXrSfSYV2Bqc1q6aqYvBRmM+aB1EAAbd4283nPpFKMRGb6vP1D08JLlyqh3OEhtsGzeP8wwUPdzZYdx7JlXlcYnbsxsPxNlnGxYGaIz9ns8BjqoGMRBCWJjaBXKEC1dgotXE1iBSwbsCW/L7MHx3KQLOl2SRGJivQReGtRc7OFmS2W/dvze60mlMDRR16LjrGza86G/CxALjfNPfShGm6jjOIIBOKLfrY7HuUo2buhWM

interface Person {
  name: string;
  age: number;
}

interface ReadonlyPerson {
  readonly name: string;
  readonly age: number;
}

let writablePerson: Person = {
  name: "Person McPersonface",
  age: 42,
};

// works
let readonlyPerson: ReadonlyPerson = writablePerson;

console.log(readonlyPerson.age); // prints '42'
writablePerson.age++;
console.log(readonlyPerson.age); // prints '43'

XzTlahr6SO0mJUI6NaSoPtblAN6+kly1xbxDsE/w0hCOmfIVIMQJjaknL1KDA0VCh8jzabw4btaRLwywA+FSz44QZCJSi9v4NlM/owkheZojLZKLy/3+VNqk2YR3xihZ2j2wHrmuS+jnFfrMxK9kc5m1Z+GsiQyfjUuAp8az0lY=

索引签名

X72Et+NqUj/1IdzvTHDRVqUHa+8Qd2mwMftRpB5qibeUqp6LGtMi0QP2sl/5LzxwYzXri1Ja2DFU2Khp4L4uXUMRyUazzU5GjNsYH4yksbF976JgXd7mlMI9L4XXHPjF

wHapcB46xYx8TYmQwDkjSY5McP+FAu3jRF6fPhzRIeDZP1PFK5mRXHgIMWyoYwOA3lxmnkwzVRistKllINRhiXziACn0xQx8h6lEC8afUUIGDUfZ5k+F3p+6VRsUPCEm

declare function getStringArray(): StringArray;
interface StringArray {
  [index: number]: string;
}

const myArray: StringArray = getStringArray();
const secondItem = myArray[1];

5iFLqxbPEu2/uWSSDPtxmXpfs57HskL1R4IRQE3siTROYFLfa7riwU+QI+HS2ufzX+046w9iNGa6D5lOe5Cxx9ncYCGTxk+r1uTOovA1XDIF4n0gLZnCKVOMGRu2kF3WsUx7maRRxn4A1o3D7pdPOKITSPS90X2rpOZ8O7YnTeuBOyGYRrKS1ASvNpUBI55Ym5HtD0i5YkzyTUAJXsnt7fTTTzQpzNo970+/hoMbEulXQ+fPvcRgsGZfhVwPpqihb7YcL7uSKaeCKqYACUJlZwZ4vjkTBLLl5qCiSOkHgJYZjioOVDpnUkQ3Qqy+bX2O

bFDlL6de36Q9Raf5Q9bU8/I/dy+cvm9H6ni5QfqvRyvMBKnVjYoK/bx9+0j2O2LjDRyeGt3tge799uewAo+lB5fWZyWfs0H1K1yoB5IFO57KdGh6oE27mrpjpebKleD2f9s3zTlL4NFprbxOyLUioi7VzwmesOdoAphIAYd002Dw+YdZiT3fOBqt5NDgiXyU6OlfeMs6ig510jHSdkzPgZBw15Gqq9PLbnwu2TEmS0Q=

7lOEYyUKogWctXdAjsdRkW6r6BRx8zfNIAes54CUrPGi/gkjvD+leZi6a8QvKv2qbs2MwL12445XHDJDQCNN9EIvltXNapwy8AxzREljNkgzHwTfue7cSGbX2DI1Ah16rKS9D4c7nHtdNKp1JWlpOcBP7Sef4F2NRIk0geI6exwh4s2nvwCQn+yh0ofAVG9Ct3pCTe4DGv7EvnhpopO9Z0OefGfvysieC7CQ7IlZuPMXkuntODFZAXDuwlKc+zQwjKm5eYcJpFzWDgru88wFSIlvTTawOFrjMHszOcntza73vVRdy1UqOP+njwKYStgLm2hJEov3n9afLjDbSgkn91ysYy065zIJ+oypo+/qW1fRy5l7QFsUuqY69x7wYXWnSZ5iXpmuCt18Q/2FS2htYFC9N4g6XkLjPQoBf2l/E3X5mYZyZqWlejIzYxBUgZf6fSI4F00MphntURHP/8OXEejjQuR0xjjuujwyUg6elC4=

interface NumberDictionary {
  [index: string]: number;

  length: number; // ok
  name: string;
}

9Usii6bZzBuPMbS/ncBm7JGEeHY80vVKiipE+d3sJxkOKPksPL+Z+HhTlzu8oBsZf3HBZVuUKjgLvcrCIReSDwEnyQSpuzrqZaPOILZZ+rJYNCRw0LOSRcQb48pqbq7T

interface NumberOrStringDictionary {
  [index: string]: number | string;
  length: number; // ok, length is a number
  name: string; // ok, name is a string
}

v/dZxPGChuFT+7jig169P+wmJ9o0GJs/VftCMUI57wSVgUR5jwCpn7zHT5X9iipV7xof7jQqmtj05qO42us/YASskd3oV08n5D1IIlHl7mSyxGFeIV7J60kfUzYZyqi+

declare function getReadOnlyStringArray(): ReadonlyStringArray;
interface ReadonlyStringArray {
  readonly [index: number]: string;
}

let myArray: ReadonlyStringArray = getReadOnlyStringArray();
myArray[2] = "Mallory";

wx5u0FRWSYxrilQbeq9AaXyr0CcXDUGxmqHEcvL/WV9Nx4lsDwcNGgKdK6rJ/tx0+S4RHrx3eKQ5kWfXpPBq/14o1V029bw0RKVZlDtT743rSWpDUTvZp51EnelC0LEM

扩展类型

J47+XAKrfEjgxyCqWMseRb2C5V8SWaHhywrgKtn3W7T/m6pxuhdBhZRlnMeqZ14MsSv2t8JacpTRtFnRaTPoOGWfwlm/gnmHC9EZLh3d7FZ9p2xncJ+4yxQh6pWzjoPcPoKQAZiV7nH+kyRq9yf1KonlmpfCLZDMs3qchZgONpBlyARRkhslLCiGWcIwuuhAYi1Cwm5LEOSh4MbttN/KOwLXQRUYFurXki4wjdY38KGYwQJ9sw4YFNGCP9WBoIWqml2Puob/NvIASruqojX9Zw==

interface BasicAddress {
  name?: string;
  street: string;
  city: string;
  country: string;
  postalCode: string;
}

NpfuD2GtLYyhGWqDGo+NEy9/NH9t8WR1aYbRIhXvua2VcaQQz2fg5GZKon8L1l3IfBhHN+6cFlhMSXDb2JA5kADmGkvbUN2Tq0ysZ3RoCiq3xwa1bhxq6vSEJ2/uayTldgmmw34/nuSLCFxurrOlX5HC6LEuI9UX+T5p2rmztY6r6+4sDAO12TvI03yC5onI7rfgWxhAP7cbLP6aNrsthh14se+nH5iC+8Li3lc+UQQgTcM9b+yK3yl3cm8WO37uIGHCE+g53CV0oPdF/dEYSQ==

interface AddressWithUnit {
  name?: string;
  unit: string;
//^^^^^^^^^^^^^
  street: string;
  city: string;
  country: string;
  postalCode: string;
}

L97aeKAqWusvVU7RIDQ8shDx4KuiEy9WDX2lfuKcGWrfARWNc0ewdJz92TV/NjTEAZ34kDbXFXXQuFkC3a6pQDuWeNEw6luvXFdn7A27afXwZgA1PV+zX8pBa75IMwrrNEGhVqPNOtm/pCYSy0qEOQQ60odS8TEegBh26jd8wwMHD49SzFc5YW6VlwI3xTMfGVHI7J8elFca4ARZRzsm5Ng/y+kKkjUHCnN5VlKf/3DqDZEUwOmZ5r0jMdj/yPlhxdUtfXAYgT2EXAH1dHo49qx97kfxGcbakUuzCzS42h6dp6HntL1haMpo4K/dZIRdza8tEsbNdQh9hRylyU7UiS0NlgABH/Rfa7B+ovtYfU737tqcKRXIO/U7QbUxEkATMToeQi8nymiEH00HsRwymQ==

interface BasicAddress {
  name?: string;
  street: string;
  city: string;
  country: string;
  postalCode: string;
}

interface AddressWithUnit extends BasicAddress {
  unit: string;
}

NAKwRGswHr20U8KN0gL6nqGzu/K+JbBfzXR29a+ty6V213oK2wf3e4th+GxXuyU0DJKr4iYKltlWDNSo28jX4PosT5+VIDBVedm6gxvtrOr9BRWMW2QNpVx3TSLEio3jK/mdTEAWi4hSgqGEKbJlMAozCssuGWV2eFxY6Ua9HuSXhacVc7iYGJwP/f8KP+HoCeu9ENk16gRtAl4fnweV8CBReGYvJ3U/ZbVQzsO5i7kOiWdCzPJ5VGqNveT/RHBsZ8hFMulTM9s7a9yfZuNheU9z1delyY/aECh3M//GISiMbKkXf5PMBO10lklTyQJdcwuUJz6LUbHuHVIfpcskHV3zNoStpcIVmMrm3d4n9jTcbQtcTC5l85c1df/VYRfy447Kwybi9g4BqPqdhBtyCxAXF3YnTpMJ2m7tajwVwL824vB3IHDaw4vPJOJ6cFZ7nxsKa1dM8FprjkjOx7x4Ns/KYjnr3i/9DTj8veiTYVk9E639DwwrWyZXOn+RZKAyrf2TwH8CqI0EELtqaxKss4/g588+jmj7gLd9aoeJsVJavGAVC2IsEZHmyMGZCqX5Q6Z86DD7htXGJYBieUXAsaHcZYNL3Y9xcW+i/oy7rPzCxhL0l/FHTcAWMXNSsqxfWkkx5laE7fa50YZEC7u6++r+9dmRknNRJ6DW0zMJdUIhTEUj1t5k/cG+t1ZycHPZ

NAKwRGswHr20U8KN0gL6nuSX7480QTeG7DCfIlo32O6FWfLrne+DkvzWwpz+MAhbMG7aTMwP2u3SKqllVwuIIA==

interface Colorful {
  color: string;
}

interface Circle {
  radius: number;
}

interface ColorfulCircle extends Colorful, Circle {}

const cc: ColorfulCircle = {
  color: "red",
  radius: 42,
};

交集类型

NAKwRGswHr20U8KN0gL6ntFS+AOpKe8HLkL6oeoaPXmJptH5NtiGhf1IrnIbfLIIhprNK+L1BNPi7E6Dc/ky8UL0iNNHxpNY+z2Dj5B7ADN6zkc/Xi+W+y86g8MJEbjZXXq3aVywmqVWElU+UFdNnbCW9H09J4jciC4Ldt2JPi4uhAHOwvBBzdTYIlz9VuVGQ3PTSz3/zbQ1s0GyxRf3HCpuEgmYwUy5BB8z0rubrQ21K5NiDCvejoQnrrkRLA4T

ifVYjRQ8Jxc4gHZcFSZCEMAnNuhCFGQnTa30KefL0YbH+bFN6oH0tgWZh/EcYcWFIOz3OjuJEUn4Z7lXDs/hig==

interface Colorful {
  color: string;
}
interface Circle {
  radius: number;
}

type ColorfulCircle = Colorful & Circle;

PFoaIwRd9eZkFbux7utZtcHf4WpzU+CHi9YaE170wghqu6IWzLRcV2B6jxbvcE9Z9jrujzyUcbXYHQ7WQmceHViOJvTUVckc6BN47jBPsep8vd2A7F4WLzFGzZlwbCTucF1/supNuZr+wOcpfLxEaRxzOwV5Eiqagl9hRM4stfRlKeT3v7B0CVV5iDPFI1in55g/uh3twH4EpTpgcEaVIR2BXAUMpztotV0EvVOEcaE=

interface Colorful {
  color: string;
}
interface Circle {
  radius: number;
}
function draw(circle: Colorful & Circle) {
  console.log(`Color was ${circle.color}`);
  console.log(`Radius was ${circle.radius}`);
}

// okay
draw({ color: "blue", radius: 42 });

// oops
draw({ color: "red", raidus: 42 });

接口与交集

JgvrQ5X3NYqxiEMNmURx4tt5pgpO6QKU64SFkju64tsVVxqbxb3CSN46hrFoKakppjC23wCUOX9Gsl6693B38AoBV7t3hY4SlilSA2jxMbGyd3ILAuyKP+OHyQiGXp3dZlM9JT0eD5SdmoN35BIsyMIZp4B1eCDSiikGWKcczSGge4MTr52csr4sFIHJT5YtxlqaSGq545RO8XwbCaPbiUOBXPvGAVB1qmzThuBOhDuNTmG2WEBh8+RyWoWzrKbFabaC+EPl9CDvaoH0lXuCdKVT0MTuUdnbnvswAfvBq1GE4TI2MciMXW8dNvtlgrhckRJpEWLC7vM0DyLBm4nwYw81wYlp0/SxrLG/BuwgvR2pXDjIs1nAGdrMfDVc9Gu2TqexLIczngzl2ewjSZYgy96qt+gcXRWnp5N0SmvDNN3O5pKDOBo7+fVzlO1ILOaiLXnlM5UWdt8JsPlZnDwQ6ZHJe7pYRB4UgMjR0BmTefrcQFVpHxZ0pRFLf6wwuF+2JpJSNxix8RslhMsvv1hguNyFL7jM4dct3lbyCJ6VV6Om1jzEqtpdfOXCojwKrtor

泛型对象类型

/4mmze7OADud22Z4OjZwpi8H7pG2MovKgYrFjFf5fWgLBzUoy8GnJQV566PXLdxGvl36oyIfUb2nTdPo55mQqWEJ6ejBI/y5AcswPSUBa6dGD+GlG+/TIlquYCjgNvbj4wk9pjf29rWqYPImZp1Zc9Q4gkmIPCPSLNi54HNZIhlHF4UCrHogJVTQ4Rzj9HUC

interface Box {
  contents: any;
}

6MuxghIKGX+ZuportqzpgoGXEWzIMAaFXjlFgsCVBUjC0AqU0DpJx1BL8SXb6Id2N3CeBzvgsnIE51PNcJme/+xHKXC6+92iOj4+0XnPEIKYJ3R4EFHduXIy91Ig6DWjDTyB10SuI3duqKr2F/1FctYWs+eWlZhpEH+lvin8BQo=

/zqMLKHMfimguD9dYNDhmWYL9//gsUdAIySNUwJcPa6Vroiley6OLh/1b88DySPj19P+QSKxZoVx4zp0bHVtxqtFmB4T5+Y4OgOGvwcp5LvlBi/ipokIF9nh+RMxN+Za76xZix4KXAdcgGI+jiVNeaBbpCtvNO2DS2hLj+xGUCK19kdbom3t+cAJFf48KrED/b74GLUUWNhZcFMK8X3NujLYWLDyrC38tygF/nAgsXG2AwhC40/5r5WyOgyxWa5Z3q6V+at4O8HSgvI94Xs85w==

interface Box {
  contents: unknown;
}

let x: Box = {
  contents: "hello world",
};

// we could check 'x.contents'
if (typeof x.contents === "string") {
  console.log(x.contents.toLowerCase());
}

// or we could use a type assertion
console.log((x.contents as string).toLowerCase());

Ef4BOPOJShjX6cCHJIE/bi/g+1PgCSGy9D/RG5AZC6dwdMW82ntM594pKK8Yk6LM0KMaD/EmKz6KdAxdQgkg49Rh5OvyNO/4hZXQaO2XFlzloQ7gnex+QAMrSPbUzhkK1phAXM1UKfauJ/rjjzmu9gpRi5WoAnkY74QkHck9fH0=

interface NumberBox {
  contents: number;
}

interface StringBox {
  contents: string;
}

interface BooleanBox {
  contents: boolean;
}

gLT0/qVQihMJnkgqtDFpexc668JNqDNVeUqpkGcerSr4ndNUe1RTMVh+5oLIGGANGnR83Uo0UAEWYveqjS8ao3Vmj7C0uqmt1eb8RGMVO7u1FB/nn2SIckMfamkBIEXdw6c3Rx4AYbj4dd6neO+KHA==

interface NumberBox {
  contents: number;
}

interface StringBox {
  contents: string;
}

interface BooleanBox {
  contents: boolean;
}
function setContents(box: StringBox, newContents: string): void;
function setContents(box: NumberBox, newContents: number): void;
function setContents(box: BooleanBox, newContents: boolean): void;
function setContents(box: { contents: any }, newContents: any) {
  box.contents = newContents;
}

mDvOewkmsO2WKC0tJmP+Z1n7PpMxr9GnNR0k/NKwssQMWMrA7b97OG6SocSWmUFQNGC0D49UU53aIkjUFxJBPreqicY+AovPiVaLMh9YBoBZVq0OgLLLxNj0PJW5Ka0lvcoc3DbzKHCvlARABxYCAoi1Y0H4XkcSQA3W5TTumf1dv5VnYAL3v3A2w+P+kzAWGEXI00aDLF6nYScrWjWLFbQfoe+H5zwYjMbRhzHhOOY=

Ij5lmjNkMaurSEO31JUxTMH5CCkxA85zyl6E3MGWzVRjFMN9cr05FCtcF6c+4aRFTCEr/u1NrdNjeQZIeQumn3poigRLcYASUG4w2SwCGuyXDVuPvFl9BVJGXw4on9DR

interface Box<Type> {
  contents: Type;
}

311SqIQdnGS35MDEBwSNayf8Vc2FbupCXiUQQu8YNcQMNwg4HY+voITBBfRWY6jgF1tqF9qLnaZlZBB/dIjqTc8yCRij+VEMr/wdvo15AMYSyx9wD4C3bgZQZOPxYRTNkaihowtfdGwJ0wiJmK9yjZ3ltVk/Wpt2hhhVeVd8lpjfjdnSiKGE3zkTJIfpCvoMylSNBh0doQLN2E8dGWTbYcTIicv6iUUxdi1OkghdEnCAg+Vunz+xYlRpSy6oxAm/xMlbq+JZtr9w9FS5ySvwX6Ten+RfUNXbkQ37S/aEX2lGr9itk+rTXVckPefnlWjQMJ1aS6/ag5d1Fxg18otp47IM7nq1Ao8zNqtvSeBO2B0=

interface Box<Type> {
  contents: Type;
}
let box: Box<string>;

7qml5Y8RbVwFv4cbffI+S/c66lBM/60hLzRDeVt5nkpe/apUtla6deoKvmmyPRAIUTDgoIbfFncYjzuPbIkgCNhRgnIH+Qw3L80pPLsCPbq8VHNW9MnkRB+VrgiA6Z0XxjCmkqrP+/tEF+OQnA7C36AyWQrpZQSnJD/plYySZKnZt+01yvBKf7Yc6c+/cwZzYApDO2KKINLU4WS1nMp1BizfqTSJBYVl7qhpWZHsWXtkz+Od9vYbGsRvAlo24goJr5EeZAx8HxLeWDcHyx7fK2C3+EaQY116B7AkQLOgpgL80drD+mMdR1QqJLSe42rO5QEsyFr3OhK4aZEQ7V1J/pk0tlu52eN4wFPe5xtB0I5slgPIHKrqJyF3jD0pjad7jqfWU+r/l5Uo24bjS4miybOPjrc65LkrUe/azAeW3K+xM1GPRGfHlBcaV12S7bvXpXH1ILProSLUD2666D8mLMtmP8ip817QWMOVV9sjkZ/LpUfqb5TWTC5H9FWD10itwsFrRVUJV6EbNaD5CAEalxYw3ji367MLiUkv6wGXQqbjws4dTX5dOmyRfpGycLdg5ggWIBQa5sw9eU+HOCikCL+Ce+S7LrdawpOAAo/7kcHGm5ax7W8b+1IhXq8sF9N2

interface Box<Type> {
  contents: Type;
}
interface StringBox {
  contents: string;
}

let boxA: Box<string> = { contents: "hello" };
boxA.contents;

let boxB: StringBox = { contents: "world" };
boxB.contents;

rCYz6LQ57GDA/kaVZiG+GFiVAdm6kDwHbwXuOmhKCBOgPY5daSZsuNiwpc/HoNnd9My6qw8/OWA5UY00/n04frfpfbO7i2fPYxGcc9NEFDNRujjYCtux4QSnlpX5xOUUcV2wt5v+JJGbJ2AFYCgRznqyfBZwpLRjDPQpTyUaDF0YEccfaJk01388EQvFIWDwbJCbygnGRt2hqYW4uXb4xOceb31tS+YsxgKdZD67/cVfgBRdm5N8ADGXUxkRQ31q57HVkBAjV+JnaFCj4Lq+iVdyeoBn9iygt6LBNO4NlNToANXL5qZSpSKbMYEO15nla0dSiTR6VFMsjqp1wtsx8+zJ5slPUs7HjBoDL7oEjVo=

interface Box<Type> {
  contents: Type;
}

interface Apple {
  // ....
}

// Same as '{ contents: Apple }'.
type AppleBox = Box<Apple>;

7lMsC++dPAj50sO1s56JaUW/so3S6SLgHd7btyDTCzbtJgr2KFIkUfkbby5nBh1gh84Yk+NZxQw/66O45G/QRnsuTuYp5tTrfLVkOmeArztC8QDBlQMjJB6dkFU49ObNT59fkxZgFimsvAQhzCTJODPsO9HHcesEVRHrCnYO/Sc=

interface Box<Type> {
  contents: Type;
}

function setContents<Type>(box: Box<Type>, newContents: Type) {
  box.contents = newContents;
}

ZfqHhEntQof35VwGElsrYm+A7A+HMUe6W7bMBnGmL6dwLiriE9epAYd++QFDLPETa4jxVl2svL0lVmlkfVkQR6vcnDZrZW2YnOSATsVCTQT4MIbii/PZrDi2KX3BaotygV+JijqorneVnFbZqQ5eYIhKTvre2wPDWLwRjC2/n1AmQeYS6bnH0JSrRw8YqKs9

interface Box<Type> {
  contents: Type;
}

fcKAwRHac2CLQ7VcaDWcthRgkP+S7bmSO1BM6Jiae8vDAwD8YBs+dVbpYH2WZB9f

type Box<Type> = {
  contents: Type;
};

GMEKct5AybolZ5/2GxEdRBPJ18ic2lXtN4bNxN0F28C/xoLFK16j1nb3fCkz48+0uu+EenZzk65Cze5C6wPrgSD+fexbMLyN88RVX4JRBPXNUMfB3VBgYdBJ8WUbx/RenSg6XWN1vovO17DzGx8kJozAodUPTXzAY4Il/bA1UsEcnFhOXS+nxhGRL3w8iZqn71Pp50gwVetaMuBJDdybtA==

type OrNull<Type> = Type | null;

type OneOrMany<Type> = Type | Type[];

type OneOrManyOrNull<Type> = OrNull<OneOrMany<Type>>;

type OneOrManyOrNullStrings = OneOrManyOrNull<string>;

67griMnJbmQtNly1wIdWtGA3VqYEo6zZrUXRIHvISpURkBDP2UpOeijTq/cZprsv

Array 类型

SjtiHZ0hnUX4pao40l3sClBMq+w82u1VAoiLqTw27WskQmmE/u0eDKLMbohw7siI8INMViCpXLU2z/sPkE/WJVP55RuCdfFjznGeO0OUU/ZBU/QftM5kCMsROrfAZfZp7B6obTacVxST7etDrvvrGAgPRsIEWKa/jbqf9j9Op0v/kixiJbC13ohURoZH10ZLb0CedR6EGX2n0st7rYSmJ8CN2A7mbIDq4pAiEsXR7/J3rXgNxjFTuJ2pRvqRYyoLsE02eTjhKUPXLlAgsSofLA==

TA+QJGyMKSdgerRGL4cacODLDkasID3fEP6k6MQ/u5ya40ob4f+57hnPvqd28kD40yVQIhAcTORg8/iIopqfes9fbRLLCxaxNhb8eQqc+KLkCjh6R0Kp99R3pymVok/7R7AFdE/vbdAf70/QYgNchmSg7pdKXqXY2ynoca+3AdR1yeqdCYONjik+NtE8kSwYlic8tkXMlp3ONLV3K8pz4ehJNlmEIvhPpoOmsZQIy8rx6Olh3E8t1gk3NVJh64p6EbPL/Inq4aGC7+mc4/U9sqmEJuppIOIuCpFdw/mpmQ/3GyQ9OkA2kWt8CpQGv8n6ABH9DKrg33zOsyDQfb7E7I1IEPSwC4lgoVXwxw9UEV+8xuTal/J7e0NWTxEV4R5T6Xw/MwIcr5YmG2rZQzrhAA==

function doSomething(value: Array<string>) {
  // ...
}

let myArray: string[] = ["hello", "world"];

// either of these work!
doSomething(myArray);
doSomething(new Array("hello", "world"));

7/I3LzzHgwLq4zjncBixc7HWiq8Oe0pPiYqVJLl3BLT+GzIFAHs+5oh5hh/jOsa7nt4Z1KFYt/JgqCpRYBliHbquqYGzoE9KT+K450l9Y/jEZl4/q0AM3OJGoTGkJGfL

interface Number {}
interface String {}
interface Boolean {}
interface Symbol {}
interface Array<Type> {
  /**
   * Gets or sets the length of the array.
   */
  length: number;

  /**
   * Removes the last element from an array and returns it.
   */
  pop(): Type | undefined;

  /**
   * Appends new elements to an array, and returns the new length of the array.
   */
  push(...items: Type[]): number;

  // ...
}

MMbrXBW0fa4fTBCllhqnaxd6psjuzutIdEY9vcGAfy5yEbnJ6Py1eeqcITXo2T8/R8ejpmjNRU7FX5VKhdhC2KKUTZMo0FjEBk/eQk51D9Cdldzj72q9T0Lt7kKt2Jk/XmyteHp9hGeczC8Xxi/Wc0+2LvupDY45lAOpaK6GOeoVjkciUtFaF+yqBSe8ZXdJM6m9pBJqv/6A7wmXgfghJSEBJB/2flK8YLXKfixEH2DEg3fUHOzXt1tkqvRSbsqrM4EtGuegtiD6AX/HYyZ/SZMfg2G8rnj7Z4EGrRCf+UzOeAgzxgTJSnsqy9K4zg/8TkXlEcAZovnSp0WUuIe2FUa7B5OidVdTtm5wso+JXuB8AmAt7ZBR12/gslkGrFDzscw1550xydiSdaGj7LsVt/lRUG/4S3Gtwkd36cNL3OYjtaoOQ0edCfhnaD1PyPuo

ReadonlyArray 类型

7CHRiXfPj9QJZ2gk6SaLZte4yJsTCY9mgnTUqAQPn7RlXwu/yFIGb15GcYeHCgfinN8NcQMhu0L4ZXErKzDevOChA2NJWxtPtMGTSOcEU2DwR6gW5ynX8pj46xRF0OUC

function doStuff(values: ReadonlyArray<string>) {
  // We can read from 'values'...
  const copy = values.slice();
  console.log(`The first value is ${values[0]}`);

  // ...but we can't mutate 'values'.
  values.push("hello!");
}

qwD4NEiFISaHcskc4pGLpH7IgnA+hKTT9y4O9Rq7FF8KGyjQH1vr7S+oIBYIX6yMoMJ2woYqyHZ2mA770cMWUxOyh1G+cjeBKsIYpfo81AOcchRPOUyWlqWPv8j745QFKLOk/AnG3RSlxHXwrJHrg/irr5pgUXLNyYL5QFSaWDLgBa3oC5iM2osBd/Dy7p4QhnNnPTd3fqBlcJWjO5P7UecAGzjXyYp7QqVXv2QnKASXXzW0l52YDdlzljEPKX76MRZoqu7j+sBNsG4hjgd0bSjF/Cq2TYHub8bSLrA5wguFb7nLBvyIMkkAs6mAAIVAoRCCcabSoI0uLcMfTLeD0PsL4T5i6ZWPV6N3RlTiEUpN9GyzBLK8on0HaTWa5WJvC7fEy70/9JeCHLbMpqLYZ0JbxI/OSO43AmMjS8u6PubY5tNx/ZhvjH9v/eziuhuUqUNxGxlZvT42l9AjcffHodxDAnGYTybBbVoizGnSAEbKwSpZZHwuoWVr/EVABbMo2ENRpgOlZRRmM38yDJ5LQQ==

yqaajWPuffhtWB3/OM/I4XNFNJi0/sCJj7WTKG1n3dSXd1lh7dPe1oxHVBqFGpULk+uf3GKAf9hbSFat8qnL04PbbaA3usHDH63H4MXeWU6XxIxiEDkG1W+FPBRq20Vqm08DkVd0DeAm4L/puEqT4A==

new ReadonlyArray("red", "green", "blue");

Ij5lmjNkMaurSEO31JUxTMwbx3QUsd2J7YBSPOzcLmtTu0ZTvQBGFtereFlWDHkyUdz6BiLk3NxfTOmR/jlQ2vRloHdfVY0EQ2uNbI3AahE00Jdz0uRJR16GDn9HAD2X

const roArray: ReadonlyArray<string> = ["red", "green", "blue"];

lSHEnYSq7bVmX+5E9flUg8i9gyn73LuC8O4KII1KhKNrQntqnazHpq5/hHJ37OuBcibdYO7I+lEUv0mWSOJfmD71SGN02DjPIBBqvgtRxJttULmFQukWPqF5OWNVmm+eI4DwqJGIal23r4W5B+/Z85rzJQJNZ0vkzfM9MuNEP5y/kIvLheu3P/5sGvPlax0AvTFS2ADW800JHUSfXiKhwsH54xk/CIlNZKGjmlTyZCq9Qhc/c3YIhfyBAX9Tai4eio1ewuctdCF28Co//VqC8A==

function doStuff(values: readonly string[]) {
  //                     ^^^^^^^^^^^^^^^^^
  // We can read from 'values'...
  const copy = values.slice();
  console.log(`The first value is ${values[0]}`);

  // ...but we can't mutate 'values'.
  values.push("hello!");
}

vWgxqwMU2hrtJSfsS0r6JJ1iuDhpiPoijFNfP02bgF7flM6l3L8lgzzM40VXOQRGncK8GHxP5H0lwbRWxt721zn48oyeW4JezOSgbWQAErPwCfAk9ZVPyWpYO0RFT274F/aQ4A5R40g5xzYCXnbC7GfdkAAmKCk3Hvx4/lCjv5RDaiqAkjVFW27cHLq4ysdTTBz83xac/6egsV96LRRfIj/Bv6DP6UTmIzqKH7NMtnt5deUsNKz++q85yQxLqi/h

let x: readonly string[] = [];
let y: string[] = [];

x = y;
y = x;

元组类型

LCJfaCSpRnz5HpUPjy9QCeNy102c1g+FV+P9SOrrMHiaKbVY/JaM7FU9l1+DOrdMqqCMMUczAcJeLRAyoR83sFSlmSAesgj0eI9FBig4Zj9zBk1SeueAdmEaTJn0/UWW8KqQnmwZFSBDM4rT9dzyY5sIud8Wno1zQx86bjhbmB5I/HVwqlAY1LLLVdOdmyMy

type StringNumberPair = [string, number];
//                      ^^^^^^^^^^^^^^^^

T2G0aET+dR4zRemMUk2LmZHcpAHYhGjYPpfF59ZiQdiUd9Vl2HS+HNEnsgSfTHaZ7x64uChfDtkVOCdg1RhzaDp5rKb7h5IW4ixKECdgCBfdl7PxuvEGKLBpyJvWOI+21HJNi1VR8t5lsdwMy0lhDdndsZx5cosTcriJ5/OrsbNrxeYePI2zydoR+sYSwjRQ0M2mZPbs+tSBmAGYsD8hf8IY2av6aDXAopMP4wqgtU4g2UErv5AUR5Qq9OtRC7IXprskzh6mY23RoHONT4hZzjHEgisGu3Xk3oaZe9QXzwH+d9V/A9M94tcvYrrhIfOm+ReS+/wse3d3Kh3yF8HKHTH3mEID5NfMWhbjFSKZ6yjgaXwbw15rDdHM8Czo17A+kZJtwFh/uTwxAuKwh4NbWcRHU3ml7Qizyvf5gWmmwLa1tCI5W44aMKGXbW7dyjaBhC2urQJOnMCSMsTNfLMaXyQXJ9Oh/Ee+VGm39lTfX2Xz5DGVEBJmD5cm0AiSIICx

function doSomething(pair: [string, number]) {
  const a = pair[0];
  const b = pair[1];
  // ...
}

doSomething(["hello", 42]);

JqngJuajWs5OAmGoAmuiMaJiY5qlDUScnEzlbwEMfWPsVb3cYQucUN0viTisQsumXkoRTERZSR2IYMsfNTRuqxN6/iqwjaz9Tg2X6MJSoR0=

function doSomething(pair: [string, number]) {
  // ...

  const c = pair[2];
}

SWKWc6oPEKN21aRL47RrnlA7g73Okx7/Cw8Wzt2yQwmwQMw7ajSekUvvrtA2dDr8pF5arvI4n8+VKbj6LTzqFnvJw35Y0oQWVz+8N699qLJFhfBgQvPBSM5rw4FTmCdPe183mb+jJ5aghN8L+aMPY+rCEIrBCtrtSueJ0q6XK1I=

function doSomething(stringHash: [string, number]) {
  const [inputString, hash] = stringHash;

  console.log(inputString);

  console.log(hash);
}

1pSkjjxVQuk3sTYlKI0mphzhGt6f4lomX5uL/cL7PzcMB7eU4AZgSx1z/yTX3dExeXSFK9QFjc7ch79EHdOCIFf5rOjFIK41buEnUsGLA8SE9mjc6zz6CK1M26VBA8SS8p/M6aFUudamjlWsbuhm8xqEBDzban8oZ+jiPxlWndpbI/XuLC5Ti9WqlK3GwgOLlcRjLs9HhpPsJxI3rVb0IYVO7CTTctKQnUA/zRUsUjX0jsmrvCBx9yE8sKp4z9VgBHZJAX/KFqUQdRThaRnUtEc6fQ+6W2JDslB5j7f25376kYWpUQBmIDxo44YU8/q69UKXN779+mFZ+FhsL3wyP6LnfwP8BDF8cXkawXNKLTCf8tsoY8XZbmnFYM52Q5OB

6thUA+kzNT+AkA7EhBmJHc55KESOlpu+UjmLFoEGNN+VPM6GhJDzs+wQzy9tSCXxbmgWb20wQwe7/yvn2TA1Vilv+Zzyae6mz/fmPc4zDpNCY3cVggp4AkP6oBVAcbKrOSUkh80O+z4M4RlqpjBNM3DI6ihJm4X5dmmveqlVLvt1JtbTQwBvKpJOJ38hkXzijiEYfRMJs2edPPqy/DLcCZfSwlWKqhWvqIL4AnXcWgA4nIGaUkHbWeWUtYOD8nZi

PsKDwmru18Ml8p+2Mf/OJxvqohDXP6DmZojQaQuINlNlIodd26lxzP2KoZQg08pJF3H33gv2ARcsZXcSGtys9jO7LxltqFUrKIkKek3BkgkK8Q1VHW7yf4erR9kal6f121Yc9JRf/DSmwdRnKsnbIpbKnljm9fsfr5AAGI2tLxt2QTdRNpfBPB2fSh18p9QhyfILtRLhfnHSOb9kiESy5Vr7x3ImAnujW4gvlVL9hX2ckkDgVyB6FajxMe3wjHokFATeVxdFmyq0R7r939kWPg==

interface StringNumberPair {
  // specialized properties
  length: 2;
  0: string;
  1: number;

  // Other 'Array<string | number>' members...
  slice(start?: number, end?: number): Array<string | number>;
}

hZ7U1DUBKFkW3/8DS5nMG5kpmi8vuOiV7aoKL95SzwqrL4Pw8ZAqZWjWYZM4Qva1cb4dCrJm97PP9Nsv9s0mtts9Ifa+EFBcV9VR/40VX1s1UTPKKq9+Q6TeaemR2UoyzVztbCf5ALDUNdZpv7eXzmp3jJS1MeJJtr0HAaNMuk3tesZ5044ZPutCrumTsDqLjs38PesjH7UvI3B9eBJEmYCt4hnxJhOu/Mh3mx9yZTTvLLkRs2vNBKHKTQu+2HvTfqZeYiKyr61yxgGjN8cXTejDqmLP8uy5htx63pi5QNQ=

type Either2dOr3d = [number, number, number?];

function setCoordinate(coord: Either2dOr3d) {
  const [x, y, z] = coord;

  console.log(`Provided coordinates had ${coord.length} dimensions`);
}

kXcqwtNSz0BNYbbQ7LFendw/2Hs2r9IpvzBWYNig7sqDpFdaNpBBSGQ6eAM66t0iG29OLWUYexqVwbQUjCCnK8FL1OHEdUiuh2DBpe1Lqzc=

type StringNumberBooleans = [string, number, ...boolean[]];
type StringBooleansNumber = [string, ...boolean[], number];
type BooleansStringNumber = [...boolean[], string, number];
    D4fOJIzJ0i1G9bX2ogZ0HH3n8h3p1AAwBODUkxo9aSF+Vd+OR0BSXf+cHuS7anf1w19Si4bJzdyfxUjooIG0281RiOIiIpYHSLedepz44ma2aSf4/l0aq/5/kOS/+7vh/x1eB9UpKkHBdZ10WIKM0r2BAkboLYr0xTjBhYX6D+LqY061LAewYX5gUsHxi+HQsZY2Ga0Rc5AjcAFrbWRrUnGsuQbx/WqGxpTDhlNLy5KHJmPfFwxmxA6SAPYghJ1RGgSDu1T/8sNSURbMEhstdzQCDBU1FqhjsA78xncFFSyHTvY1JuvS7VJs7NAYDYOFrc9vYOi7B2aVaYE5kBvCdkS1hql0lSr7fHix/ziAQUgJbvT1vu5c7HuoqC8P9m2RwtaW5PVgKoOWstnwPaGAw8Ss3BY7P+r3gQH3MC8SS1gZl60MfH0gaW7V28Eo+Qys0a5/gRY/laHzJVvydJnaXsi7kHOno2lR+UJATdydprifhSz2B/FJH479HYzPHUDF7mASGaCLy5ybNKtrSv8emahK8BZ36gSWzje+LCG9k8jvjuCWYxzhHKeQM6NGwnLp0BZvm9vAQQ+cATXmoM4JPjvEIIRN3eEG7V2ePP+Gt609q8q/WgIBF88KUh/rh6uMsdh5Gbv8BeaifUrlC6HhXh4m+rvwNFRsNjXPre7Wu38XSg88XByFFrRl284DGs0ZjQ/GSUwLcl1zHfzLox9HTBXZ0opVU6/ZY0cq+aVKzma90H5yC1MrQTPgtc17SvodhkQW2Y8cshRhSEo2gKXOWw==

LqPjz6F1UpMvPnzHJljJwXKYcbfau8lSA5MDdfXrzshTJcI842dORF+QoTrpiCbqyo2pwfH/OwKI+r0V9B0rWJYi4caPAmQwkFtf6ZPY7W7QrP080t4cViyrJKKoaLNH2DCze5FPpAUErVORb8EDsg==

type StringNumberBooleans = [string, number, ...boolean[]];
const a: StringNumberBooleans = ["hello", 1];
const b: StringNumberBooleans = ["beautiful", 2, true];
const c: StringNumberBooleans = ["world", 3, true, false, true, false, true];

sVwWTj6GnM36+VNPwfoyejv1qaxZb8GKREQ7F86EKDWVA2qA4tutU2H8lrsyvbH0KxlmAwusmzzDQDTWvR+EqC7ejH85Q+2i9rK0aOnabx8YE7sVyyy1fUuljteKslZXFVCbLYCi+A9BO6d3CJG2Tj+OMfV2kMZVhXmwEsWnmzPPQ3YplZ3HeWgFoebhnkRyrqBQQYXgYfguwCYc5lxVD7AcLgKtNaJy++BggCAdKpU0AqbZI3oEc/+gTlX+aoNE/AgKWfRr3/+W2IJ/Nh5BuTOmfPLGIdtzfeZmw2+DSwiMjQt4reEIANJiu+znVWQdlzRYdRP/XFa4MH7RtPrDxA==

function readButtonInput(...args: [string, number, ...boolean[]]) {
  const [name, version, ...input] = args;
  // ...
}

183SR4v6e7P4yM4tyl/Ap44nTulRg45lqJ0t1SJb4Ic=

function readButtonInput(name: string, version: number, ...input: boolean[]) {
  // ...
}

GFDyrem665u1My+K5taM97FbWxi3gP3WgfgfHYgC2XjZSvuFDN0g5trVqS8Cwq3+ydetQMwtkqsHyu0TVwys9Eabjvbt7rGTLsm350boynkLhVvwTqgPLj8cJr53xXPWxOZDDrV5Ygrxe2g85MZX5XmqEfk/rTPbFzhSDDQ1xs3/Pp7Udoeik1AkybGUL4vXjzzqn48dKYEy6LAEw01hrA==

readonly 元组类型

DnUzB7WZB/I+0OPpKdk1OvQVCIxFlHECTFRSfKsHK/Wclnyfql9hyvRC6Mpxeg3y3H6kPtuiBd8h/0llpL2reJIrhHIXP21PyCEpFviJ8P4midCkxx1uZ9Q0qsyum0e8D9TfzwbJyeAjRsMTELkWX7UAy9ifHI5anRZ9MaXeeQrwjeeP8FMUW5dodh33UnOPTdVRbERPDOPqerd9D7BAVmBADo4eHP1bdoXU7iPqBCazljYVS6q3tvhVyMeqiGMZv/Td0JU5eazH72z7RE9HPA==

function doSomething(pair: readonly [string, number]) {
  //                       ^^^^^^^^^^^^^^^^^^^^^^^^^
  // ...
}

rpFSbvHHU4nsXiCQ/6ZaN155j6eOSDqmbU8vMuBjalhSf+6lI5m6KDMXSIZ/WltJGUxmjHRvpRJ3MNpYbFIp2Q6gLW1pFgEK3XOlmtMcyyTejD+1S9JhfQ37QyxrR/vi

function doSomething(pair: readonly [string, number]) {
  pair[0] = "hello!";
}

SU2tcsWnBY89SD+TbqS30mfLPtQ2cEV3ek8UHeQUbqba0ZFTedFjZqa3eMCFGPyEbP625Kef7RmG06RYyikT0tmAQ4OeHfL9amcxOzaDchm9Fr5LIIM3q74aSjLcRti056BXjrYRFvWV1YzxER/+qmFWkpVLsZ9HYwsjVCfVLdmdnUAw0yUMFh8elg3IVD5j+0a3B/6y7isN1Wv5S2pmstrU12S9FHVKhnRUIJZsaJ9dMFRR8PI7zqC61Rb5JcTNr1DlifDWergaATW/IozqgPJ1YHwfo1XSTnjTtowTfFfcCBZN/w1/SZggwWe66N3O6qJ9iaWvkBD7+mbAkc039DJQzllAe7fv6hJDZesXCP1OSaFF0gDC1TU7OWhB0+vYlZ36rzIrMmQU/Wu1xYNXmw==

let point = [3, 4] as const;

function distanceFromOrigin([x, y]: [number, number]) {
  return Math.sqrt(x ** 2 + y ** 2);
}

distanceFromOrigin(point);

QywyjS6/XgsyJyx0xubvcWftlw7S9sGRlatNI3NULE/YrjLF+pv05LbhhGuutBo+EGoaFvhnZRVUYEtClkGQJxVrsB7zVwrvNzPPeerySLVphElrk9l+XwiNmT2/0G5TB6HzNWlJD6ji96AZ0xAU2ons1RzVanwC/oTAmrC+PIx7FY12tKQv/bocYh0HLvL+GT2vvA3WOc1qu73IUhzII3gWmFbZ5IMIEVTkyYmJmpkyE0Q/UWeMHSGkmUkxPXIEH3Xvj/TFhfYP3wM5u/PUHc3PJ2uSS1NUz6oJCGY0P/6gzes6yHXyQZoh+Z7g6WlpprrcEYOc/68pu2kEPOkokHvySsjyS0CkOvGJhi/D6wt7Vb3nZmMHHpSgblteN9YyO/7F/KARrsuxYA0vX6KWk4A9ZpUhmhbAQ60Y7ulZPlc=