xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

TypeScript readonly props All In One

TypeScript readonly props All In One

TS 绕过 readonly 限制

readonly properties

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

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

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

// 绕过 readonly 限制 ✅
let readonlyPerson: ReadonlyPerson = writablePerson;

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

Mapped Types



// type ObjType = {
//   [key: string]: boolean | number | boolean;
// };

// type OptionsFlags<ObjType> = {
//   [Property in keyof ObjType]: boolean;
// };


type ObjType = {
  k1: boolean;
  k2: number;
  k3: boolean;
};

type OptionsFlags<T> = {
  [Property in keyof T]: boolean;
};

const test: OptionsFlags<ObjType> = {
  k1: true,
  k2: false,
  // k3: 123,
  // Type 'number' is not assignable to type 'boolean'.(2322)
  k3: true,
}

Indexed Access Types

type Person = { age: number; name: string; alive: boolean };

type Age = Person["age"];
// ype Age = number

type I1 = Person["age" | "name"];
// type I1 = string | number

type I2 = Person[keyof Person];
// type I2 = string | number | boolean

type AliveOrName = "alive" | "name";
type I3 = Person[AliveOrName];
// type I3 = string | boolean

Array[number] & typeof

const Array1 = [
  { name: "Alice", age: 18 },
  { name: "Eric", age: 23, vip: true, },
  { name: "Ryan", age: 32 },
];

type Person = typeof Array1[number];
/*
type Person = {
    name: string;
    age: number;
    vip?: undefined;
} | {
    name: string;
    age: number;
    vip: boolean;
}

*/

type Age = typeof Array1[number]["age"];
// type Age = number

type Age2 = Person["age"];
// type Age2 = number
// const error ❌

// ❌
const key = "age";
type Age3 = Person[key];
// type Age4 = number

// type key = /*unresolved*/ any

/*
Type 'key' cannot be used as an index type.(2538)
'key' refers to a value, but is being used as a type here. Did you mean 'typeof key'?(2749)
Exported type alias 'Age3' has or is using private name 'key'.(4081)

*/

// type alias ✅
type key2 = "age";
type Age4 = Person[key2];
// type Age4 = number



typeof & ReturnType

/*

type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any

Obtain the return type of a function type

*/


function func1() {
  return { x: 7, y: 3 };
}

// value !== type ❌
type P1 = ReturnType<func1>;
// type P1 = any

/*
'func' refers to a value, but is being used as a type here. Did you mean 'typeof func'?(2749)
Exported type alias 'P' has or is using private name 'func'.(4081)

*/



function func2() {
  return { x: 7, y: 3 };
}

// type ✅
type P2 = ReturnType<typeof func2>;
/*
type P2 = {
    x: number;
    y: number;
}
*/

keyof


type Point = { x: number; y: number };
type P = keyof Point;
// type P = keyof Point
// 等价于 “x” | “y” ??? 

// keyof 错误使用场景 ❌
const p: P = {x: 1, y: 2};
// const p: keyof Point
// Type '{ x: number; y: number; }' is not assignable to type 'keyof Point'.(2322) ❌

const p1: P = 1;
// const p1: keyof Point
// Type '1' is not assignable to type 'keyof Point'.(2322) ❌


// keyof 正确的使用场景是 mapped types ✅
type PP = {
  [key in P]: number;
  // 等价于
  // [key in keyof Point]: number;
};
/*
type PP = {
    x: number;
    y: number;
}
*/

const pp: PP = {
    x: 1,
    y: 2,
};
// const pp: PP

type PP2 = {
  // [key in P]: number;
  // 等价于
  [key in keyof Point]: string;
  // z: number;
  // A mapped type may not declare properties or methods.(7061) ❌
};
/*
type PP2 = {
    x: string;
    y: string;
}
*/

const pp2: PP2 = {
    x: `1`,
    y: `2`,
};
// const pp2: PP2



// number => number ✅
type Arr1 = { [key: number]: unknown };
type A1 = keyof Arr1;
// type A1 = number

// string => string | number ✅✅
// Array[0] => Array["0"], js 数组索引类型自动转换 ✅✅
type Arr2 = { [key: string]: boolean };
type A2 = keyof Arr2;
// type A2 = string | number

https://github.com/microsoft/TypeScript-Website/blob/v2/packages/documentation/copy/en/handbook-v2/Type Manipulation/Keyof Type Operator.md

https://github.com/microsoft/TypeScript-Website/blob/v2/packages/documentation/copy/cn/handbook-v2/Type Manipulation/Keyof Type Operator.md

(🐞 反爬虫测试!打击盗版⚠️)如果你看到这个信息, 说明这是一篇剽窃的文章,请访问 https://www.cnblogs.com/xgqfrms/ 查看原创文章!

Windows 系统屏幕截图快捷键

Ctrl + Shift + A / Win + Shfit + S

image

https://zh.wikihow.com/在微软Windows系统中屏幕截图

refs

https://www.typescriptlang.org/docs/handbook/2/objects.html#readonly-properties

https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#mapping-modifiers

https://www.typescriptlang.org/docs/handbook/2/indexed-access-types.html

https://www.typescriptlang.org/docs/handbook/2/typeof-types.html

https://www.typescriptlang.org/docs/handbook/2/keyof-types.html



©xgqfrms 2012-2020

www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!


posted @ 2023-01-26 20:56  xgqfrms  阅读(75)  评论(1编辑  收藏  举报