标签: keyof

在 TypeScript 中,“extends keyof”和“in keyof”是什么意思?

在 TypeScript 中,某些类型是使用extends keyof或定义的in keyof。我试图理解它们的意思,但到目前为止我没有成功。

我得到的是,keyof单独返回一个联合类型,该类型将所有名称作为可能的值存在于您在keyof.

type T = keyof string;
Run Code Online (Sandbox Code Playgroud)

T因此等价于startsWith | endsWith | trim | substring | ...

这样对吗?

现在,如果我去想想什么extends keyofin keyof意味着,我的直觉以下称:

  • extends keyof是派生自 的任何类型T,即它具有所有这些可能的值,但可能更多。
  • in keyof是从 中获取值的任何类型T,但不一定是全部(有可能,但可能更少)。

所以,从这个 POVextends keyof将描述一个>=关系,in keyof将描述一个<=关系。这样对吗?如果不是,那什么是正确的?

typescript keyof

63
推荐指数
1
解决办法
3万
查看次数

打字稿:从对象数组派生联合类型

我想声明一个类型强制的项目数组,并能够从中派生出联合类型。如果您没有明确地为数组中的项目指定类型,则此模式有效。我不知道如何最好地解释它,所以这里是一个例子:

例 1

type Pair = {
  key: string;
  value: number;
};

const pairs: ReadonlyArray<Pair> = [
  { key: 'foo', value: 1 },
  { key: 'bar', value: 2 },
] as const;

type Keys = typeof pairs[number]['key']
Run Code Online (Sandbox Code Playgroud)

例2

type Data = {
  name: string;
  age: number;
};

const DataRecord: Record<string, Data> = {
  foo: { name: 'Mark', age: 35 },
  bar: { name: 'Jeff', age: 56 },
} as const;

type Keys = keyof typeof DataRecord;
Run Code Online (Sandbox Code Playgroud)

以下是使用as const. …

javascript constants typeof typescript keyof

9
推荐指数
2
解决办法
3769
查看次数

使泛型类型 Array&lt;keyof T&gt; 需要 T 的所有键

我想声明一种类型,它需要将给定类型的所有键都T包含在一个数组中,例如:

checkKeys<T>(arr: Array<keyof T>): void {
  // do something
}

interface MyType {
  id: string;
  value: number;
}
Run Code Online (Sandbox Code Playgroud)

目前,如果调用checkKeys<MyType>TS 将认为传递的值是有效的,如果它包含MyType( id | value) 的任何键:

checkKeys<MyType>(['id', 'value']); // valid

checkKeys<MyType>(['id']); // valid

checkKeys<MyType>(['id', 'values']); // invalid
Run Code Online (Sandbox Code Playgroud)

是否可以要求在数组中指定所有键?

generics typescript keyof

8
推荐指数
1
解决办法
5819
查看次数

如何避免TypeScript中的动态keyof对象分配错误

假设我们有如下所示的TypeScript代码:

type User = {
  id: number,
  name: string,
}

let user1: User = {id: 123, name: "Hello"};
let user2: User = {id: 456, name: "World"};

let keys: (keyof User)[] = ["id", "name"];

for (let key of keys) {
  user1[key] = user2[key];
}
Run Code Online (Sandbox Code Playgroud)

这给出了错误

Type 'string | number' is not assignable to type 'never'.
Run Code Online (Sandbox Code Playgroud)

为声明

Type 'string | number' is not assignable to type 'never'.
Run Code Online (Sandbox Code Playgroud)

如果我们将的定义更改keys

user1[key] = user2[key];
Run Code Online (Sandbox Code Playgroud)

错误消失了,但是我们失去了类型安全性。

有什么方法可以在保持类型安全的同时避免发生此错误?

typescript keyof

8
推荐指数
1
解决办法
53
查看次数

从对象数组中获取字符串文字类型

所以来自:

export interface Category{
  val: string;
  icon: string
}
const categoryArray: Category[] = [
  {
    val: 'business',
    icon: 'store'
  },
  {
    val: 'media',
    icon: 'video'
  },
  {
    val: 'people',
    icon: 'account'
  },

  ... 
Run Code Online (Sandbox Code Playgroud)

我想像这样找回 Union 类型:

'business' | 'media' | 'people' ... 
Run Code Online (Sandbox Code Playgroud)

我不知道有什么样的语法或帮助程序,也许根本没有。我意识到这种方式可能是倒退的,也许应该使用枚举,但在此之前,我想知道这是可能的。

我想做的一些虚构的例子,但我希望解决方案更加复杂

type Cats = keysof[] categoryArray 'val'  
type Cats = valuesof categoryArray 'val'
Run Code Online (Sandbox Code Playgroud)

以下内容很接近,但返回string

export type CatsValType = typeof categories[number]['val']
Run Code Online (Sandbox Code Playgroud)

或以下;我需要字符串文字而不是类型

type ValueOf<T> = T[keyof T];
type KeyTypes = ValueOf<typeof categories[number]> // Returns: `string`
Run Code Online (Sandbox Code Playgroud)

还有类似的问题,例如: …

typeof typescript union-types keyof

8
推荐指数
1
解决办法
2099
查看次数

打字稿:将函数的参数限制为与特定类型值关联的对象的键

有没有办法进行以下类型检查?

function getNumberFromObject<T>(obj: T, key: keyof T): number {
  return obj[key] // ERROR: obj[key] might not be a number
}
Run Code Online (Sandbox Code Playgroud)

我想指定它key不仅应该是 的键T,而且应该是带有number值的键。

generics typescript keyof

7
推荐指数
1
解决办法
5560
查看次数

TypeScript:如何处理泛型类型和keyof运算符

我尝试编写一个泛型函数,汇总数据库更新的更新数据.

传递参数:

  • 记录要更新
  • 财产关键
  • 一个新的数组项

即使我使用限制键的类型keyof R,我也不能将具有该键的新对象分配给Partial<R>常量.我收到错误我该Type '{ [x: string]: any[]; }' is not assignable to type 'Partial<R>'.怎么做才能使下面的代码工作?如果我用R非泛型类型替换泛型类型,它可以工作.但这不是我需要的.

TypeScript Playground上的代码段

interface BaseRecord {
    readonly a: ReadonlyArray<string>
}

function getUpdateData<R extends BaseRecord>(record: R, key: keyof R, newItem: string) {
    const updateData: Partial<R> = { [key]: [...record[key], newItem] }
    return updateData
}

interface DerivedRecord extends BaseRecord {
    readonly b: ReadonlyArray<string>
    readonly c: ReadonlyArray<string>
}
const record: DerivedRecord = { a: [], b: [], c: …
Run Code Online (Sandbox Code Playgroud)

generics generic-programming typescript keyof

6
推荐指数
2
解决办法
2823
查看次数

打字稿:推断嵌套 keyof 属性的类型

我想定义一个数组类型,它必须包含给定类型的嵌套属性名称链。

假设我有一个类型:

    type Foo = {
        outer: {
            inner: any;
        }
    }
Run Code Online (Sandbox Code Playgroud)

现在我想定义一个包含 2 个元素的 Array 类型:

type PropertyList<T, K1 extends keyof T, K2 extends keyof T[K1]> = [K1, K2];
Run Code Online (Sandbox Code Playgroud)

我想像这样使用它:

let myList:PropertyList<Foo> = ["outer", "inner"]
Run Code Online (Sandbox Code Playgroud)

所以我希望编译器检查包含的 2 个属性名称是否是 Foo 的嵌套属性名称。

但是我不能只用 1 个泛型参数定义 PropertyList,然后我收到这个错误:

TS2314: Generic type 'PropertyList' requires 3 type argument(s)
Run Code Online (Sandbox Code Playgroud)

知道如何推断嵌套的 keyof 类型而不必指定它们吗?

type-inference typescript keyof

6
推荐指数
1
解决办法
2781
查看次数

列出类的私有属性名称

我需要使用类属性名称的一些子集作为映射中的值以在类内部使用。在下面的示例中,我用数组替换了地图。问题是,如果属性被标记,private它不会在keyof列表中列出。如果我需要包含私有名称,如何指定密钥类型?

var keys: Array<keyof A> = ["x", "y"]; // Error

class A {
  private x = 7;
  public y = 8;

  private keys: Array<keyof A> = ["x", "y"]; // Error
}
Run Code Online (Sandbox Code Playgroud)

对于类外部的变量和类内部的私有属性都存在相同的错误:

类型“x”不可分配给类型“y”。

private typescript keyof

6
推荐指数
1
解决办法
3169
查看次数

预期有 3 个类型参数,但得到 1 个,但它应该推断出 2 个类型

我想知道如何正确推断我的函数的第二个和第三个模板

假设一个简单的界面

interface ISome {
    a: string;
    b?: {
        c: string;
    };
}
Run Code Online (Sandbox Code Playgroud)

关注作品

function pathBuilder<
    K1 extends keyof ISome,
    K2 extends keyof NonNullable<ISome[K1]>>(p: K1, p2?: K2) {
    let res = String(p);
    if (p2) { res += "." + p2; }
    return res;
}

const pathTest = pathBuilder("b", "c"); // ---> "b.c" and intellisense works on parameters
Run Code Online (Sandbox Code Playgroud)

但我需要通过指定另一种类型来概括该函数以使其工作(我不想传递对象实例来指定类型)

所以,以下不起作用

function pathBuilder<
    T,
    K1 extends keyof T,
    K2 extends keyof NonNullable<T[K1]>>(p: K1, p2?: K2) {
    let res = String(p); …
Run Code Online (Sandbox Code Playgroud)

extends type-inference typescript keyof

5
推荐指数
1
解决办法
1532
查看次数