TypeScript 不完整的泛型类型推断

vlju58qv  于 6个月前  发布在  TypeScript
关注(0)|答案(2)|浏览(65)

TypeScript版本: 4.0.5
搜索词: typescript, infer, incomplete, unknown, generic
预期行为:

编译器应该能够从函数定义中提取泛型 Item 类型的信息并推断出 string

实际行为:

编译器能够推断出 Names 类型为 { id: string },但 Item 类型为 unknown

相关问题:
代码

interface LoaderConfig<Key, Item> {
  loadItems: (keys: readonly Key[]) => Promise<readonly Item[]>;
  getKey: (item: Item) => Key;
  makeCacheKey: (key: Key) => string;
}

type LoaderConfigByName<Names, Item> = {
  [name in keyof Names]: LoaderConfig<Names[name], Item>;
};

function makeLoader<Names, Item>(
  configs: LoaderConfigByName<Names, Item>
): void {
  console.log(configs);
}

makeLoader({
  id: {
    loadItems: async (keys: readonly string[]): Promise<readonly string[]> => {
      return await Promise.resolve(keys);
    },
    getKey: (item: string): string => item,
    makeCacheKey: (key: string): string => {
      return key;
    }
  }
});

输出

"use strict";
function makeLoader(configs) {
    console.log(configs);
}
makeLoader({
    id: {
        loadItems: async (keys) => {
            return await Promise.resolve(keys);
        },
        getKey: (item) => item,
        makeCacheKey: (key) => {
            return key;
        }
    }
});

编译器选项

{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,
    "strictBindCallApply": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "alwaysStrict": true,
    "esModuleInterop": true,
    "declaration": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "moduleResolution": 2,
    "target": "ES2017",
    "jsx": "React",
    "module": "ESNext"
  }
}

** playground链接:**提供

rsaldnfx

rsaldnfx1#

Simpler repro

type Foo<T> = {
  getBar(): Promise<T[]>,
  setBar(item: T): void
}

function fn<T>(arg: Foo<T>) { }

fn({
  async getBar() {
    return [""];
  },
  setBar(x) {
    // x: unknown,
    // should be x: string
  }
})
zsohkypk

zsohkypk2#

这是相同的问题吗?

declare function fn<T>(arg: (a: T) => T): T;
const ret = fn((a) => '123'); // a: unknown; ret: unknown

相关问题