TypeScript keyof All In One
TypeScript keyof All In One
"use strict";
/**
*
* @author xgqfrms
* @license MIT
* @copyright xgqfrms
* @created 2023-01-29
* @modified
*
* @description
* @difficulty Easy Medium Hard
* @ime_complexity O(n)
* @space_complexity O(n)
* @augments
* @example
* @link https://www.typescriptlang.org/docs/handbook/2/keyof-types.html
* @solutions
*
* @best_solutions
*
*/
export {};
const log = console.log;
// The keyof operator takes an `object type` and produces a `string` or `numeric literal union` of its keys.
// const str: keyof string = `2023`;
// Type '"2023"' is not assignable to type 'number | unique symbol | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | ... 26 more ... | "sup"'.ts(2322) ❌
// const arr: keyof Array = `2023`;
// interface Array<T>
// Generic type 'Array<T>' requires 1 type argument(s).ts(2314) ❌
// const arr: keyof Array<string> = `2023`;
// Type '"2023"' is not assignable to type 'keyof string[]'.ts(2322) ❌
type Point = { x: number; y: number };
const point: Point = {
x: 1,
y: 2,
}
type P = keyof Point;
// type P === type as “x” | “y” ❓
// const p: P = {
// x: 1,
// y: 2,
// }
// Type '{ x: number; y: number; }' is not assignable to type 'keyof Point'.ts(2322)
// const p: P = {x: 1} || {y: 2};
// key in typeof ✅
type Obj = {
[key in P]: string;
// 等价于
// [key in keyof Point]: string;
}
const obj: Obj = {
x: `1`,
y: `2`,
}
// const obj: Obj = {
// x: 1,
// y: 2,
// }
// Type 'number' is not assignable to type 'string'.ts(2322) ❌
// key as keyof ✅
enum HTTPTypes {
get = 'get',
post = 'delete',
put = 'put',
delete = 'delete',
}
const HTTP: {
// [key: string]: any,
[key: string]: string,
} = {};
for (const key in HTTPTypes) {
console.log('key =', key);
HTTP[key] = HTTPTypes[key as keyof object];
// Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'typeof HTTPTypes'.
// HTTP[key] = HTTPTypes[key];
}
// object vs Object ❓https://www.typescriptlang.org/play
type Obj1 = keyof object;
// type Obj1 = never
type Obj2 = keyof Object;
// type Obj2 = keyof Object
type TypeNumber = {
// number => number
[n: number]: unknown;
};
type TN = keyof TypeNumber;
// type TN = number
const num: TN = 2023;
type TypeMap = {
// JavaScript 对象键总是被强制转换为字符串 ✅
// JavaScript object keys are always coerced to a string, so `obj[0]` => `obj["0"]`
// number => number, string => number
[k: string]: boolean;
};
/*
type TypeMap = {
[k: string]: boolean;
}
*/
type TM = keyof TypeMap;
// type TM = string | number
const tmn: TM = 2023;
const tms: TM = `2023`;
keyof
generic
// <T>
// [key in keyof InterfaceXYZ]
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const person: Person = {
age: 22,
name: "Tobias",
};
// ✅ name is a property of person
const name = getProperty(person, "name");
// ❌ gender is not a property of person
const gender = getProperty(person, "gender");
https://www.typescriptlang.org/docs/handbook/2/keyof-types.html
TypeScript 允许我们遍历某种类型的属性,并通过 keyof 操作符提取其属性的名称。
keyof 操作符是在 TypeScript 2.1 版本引入的,该操作符可以用于获取某种类型的所有键,其返回类型是联合类型。
interface Person {
name: string;
age: number;
location: string;
}
type K1 = keyof Person;
// type K1 = keyof Person
type K2 = keyof Person[];
// type K2 = keyof Person[]
type K3 = keyof { [key: string]: Person };
// type K3 = string | number
as keyof
enum HTTPTypes {
get = 'get',
post = 'delete',
put = 'put',
delete = 'delete',
}
const HTTP: {
// [key: string]: any,
[key: string]: string,
} = {};
for (let key in HTTPTypes) {
console.log('key =', key);
HTTP[key] = HTTPTypes[key as keyof object];
// Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'typeof HTTPTypes'.
// HTTP[key] = HTTPTypes[key];
}
object vs Object ❓
// TypeScript keyof & object vs Object ❓
type Obj1 = keyof object;
// type Obj1 = never
type Obj2 = keyof Object;
// type Obj2 = keyof Object
https://www.typescriptlang.org/play
interface
vs type alias
primitive value 限制
// primitive value ❌
// interface PrimitiveInterface = string;
interface PrimitiveInterface {
[key: string]: string
}
// const primitiveI: PrimitiveInterface = 'primitive value';
// Type 'string' is not assignable to type 'PrimitiveInterface'.(2322) ❌
// const primitiveI: {
// // [key in keyof PrimitiveInterface]
// // [key: string in keyof PrimitiveInterface]
// } = 'primitive value';
const primitiveI: keyof {[key: string]: PrimitiveInterface} = 'primitive value';
// const primitiveI: string | number ⚠️
// primitive value ✅
type PrimitiveType = string;
const primitiveT: PrimitiveType = 'primitive value';
// const primitiveT: string ✅
https://www.typescriptlang.org/static/TypeScript Types-4cbf7b9d45dc0ec8d18c6c7a0c516114.png
refs
TypeScript keyof & typeof All In One
https://www.cnblogs.com/xgqfrms/p/14100325.html
TypeScript Type Aliases vs Interfaces All In One
https://www.cnblogs.com/xgqfrms/p/16378111.html
https://stackoverflow.com/questions/57337598/in-typescript-what-do-extends-keyof-and-in-keyof-mean
©xgqfrms 2012-2020
www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!
原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/16151185.html
未经授权禁止转载,违者必究!