TypeScript 类型体操——Tuple to Object

129 阅读2分钟

前言

简单题:Tuple to Object
TS Playground:www.typescriptlang.org/play?#code/…

正文

题目

11 - Tuple to Object
-------
by sinoon (@sinoon) #easy #object-keys

### Question

Given an array, transform it into an object type and the key/value must be in the provided array.

For example:

const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const

type result = TupleToObject<typeof tuple> // expected { 'tesla': 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y'}

> View on GitHub: <https://tsch.js.org/11>

* _____________ Your Code Here _____________ */

type TupleToObject<T extends readonly any[]> = any

/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'

const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const
const tupleNumber = [1, 2, 3, 4] as const
const tupleMix = [1, '2', 3, '4'] as const

type cases = [
  Expect<Equal<TupleToObject<typeof tuple>, { tesla: 'tesla'; 'model 3': 'model 3'; 'model X': 'model X'; 'model Y': 'model Y' }>>,
  Expect<Equal<TupleToObject<typeof tupleNumber>, { 1: 1; 2: 2; 3: 3; 4: 4 }>>,
  Expect<Equal<TupleToObject<typeof tupleMix>, { 1: 1; '2': '2'; 3: 3; '4': '4' }>>,
]

// @ts-expect-error
type error = TupleToObject<[[1, 2], {}]>

答案

// 方法一
type TupleToObject<T extends readonly (string | number | symbol)[]> = {
    [K in T[number]]: K
};
// 方法二
type TupleToObject<T extends readonly PropertyKey[]> = {
    [K in T[number]]: K
};
// 方法三
type TupleToObject<T extends readonly (keyof any)[]> = {
    [K in T[number]]: K
};
// 方法四
type TupleToObject<T extends ReadonlyArray<PropertyKey>> = {
    [K in T[number]]: K
};
// 方法五
type TupleToObject<T extends ReadonlyArary<string | number | symbol>> = {
    [K in T[number]]: K
};

总结
as关键字表示断言,as const是 TS 中的一个修饰符,可以用来修改类型推断的行为。当as const修饰符用在变量声明或表达式的类型上时,会强制 TS 将变量或表达式的类型视为不可变的(immutable)。就意味着,如果你尝试对变量或表达式进行修改,TS 会报错。 as const可以帮助我们提高代码类型安全性,避免在不应该修改的地方进行修改。

const a = [1, 2] as const;
a.push(3); // TS 报错:因为 a 类型被声明为不可变的

const b = { x: 1, y: -1 } as const;
b.x = 2; // TS 报错,因为 b 类型被声明为不可变的

多个类型集合用小括号括起来;
PerpertyKey是 TS 的一种内置类型;
ReadonlyArray是 TS 中特殊的类型,用于生成不应该被更改的数组,ReadonlyArray<Type>可简写为readonly Type[],它只能作为类型使用,不能当成构造函数使用。