首页 > 解决方案 > 错误 TS2322:类型“keyof T”不可分配给类型“T”。在打字稿 4.4

问题描述

我有一个功能selectProperties可以从某个界面选择键值并error TS2322: Type 'keyof T' is not assignable to type 'T'.在升级到 typescript 4.4 后得到错误。 打字稿游乐场,任何人都知道我该如何走动?

export interface QueryActioned {
  event: string;
  properties:string
}
export interface QueryStarted {
  event: number
  properties: number
}
export type QueryProps = Partial<(QueryActioned & QueryStarted)['properties']>;

const selectProperties = <T extends Partial<QueryProps>>(
  keys: (keyof T)[],
  properties: T
): T => {
  const defaultVal: T = {} as T;
  return (Object.keys(properties) as (keyof T)[])
    .filter((key) => keys.includes(key))
    .reduce(
      (acc, key) => ({
        ...acc,
        [key]: properties[key],
      }),
      defaultVal
    );
};

标签: typescripttypescript-typingstypescript-genericstypescript2.0

解决方案


看起来您期望reduce返回一个类型为T的对象,当它只接受一个与其迭代的数组值的类型匹配的默认值,并最终返回值的某种组合时。Reduce 最终只会从 T 的键中返回一个值。

如果您选择 T 类型的某些键,则不能将 T 作为返回类型。您实际上是根据给定键的列表创建 Partial 类型。

您可以通过使用 forEach 并改变返回对象来返回它。


export interface QueryActioned {
  event: string;
  properties:string
}
export interface QueryStarted {
  event: number
  properties: number
}
export type QueryProps = Partial<(QueryActioned & QueryStarted)['properties']>;

const selectProperties = <T extends Partial<QueryProps>>(
  keys: (keyof T)[],
  properties: T
) => {
  const defaultVal: Partial<T> = {};
  
  Object.keys(properties)
    .filter(key => keys.includes(key))
    .forEach(key => {defaultVal[key as keyof T] = properties[key]});

  return defaultVal
};


如果你真的想从 T 上的选定键中获取值,那么你可以使用 map 代替......


export interface QueryActioned {
  event: string;
  properties:string
}
export interface QueryStarted {
  event: number
  properties: number
}
export type QueryProps = Partial<(QueryActioned & QueryStarted)['properties']>;

const selectProperties = <T extends Partial<QueryProps>>(
  keys: (keyof T)[],
  properties: T
): (T[keyof T])[] => {
  return Object.keys(properties)
    .filter(key => keys.includes(key))
    .map(key => properties[key]);
};


无论哪种方式,reduce 都会组合 keyof T 数组中的所有值,并且您将返回类型指定为 T ,这将是错误的来源。


推荐阅读