是否可以从`any`类型中推断类型?

问题描述 投票:2回答:1

我想做这样的事情:

interface Foo<T extends any>{
    a: string; 
    b: T; 
}

function createFunctions(items: Foo<any>[]) {
    return items.map(item => () => {
        return item.b; 
    }); 
}

const items = [
    {
        a: "hello",
        b: "foo"
    },
    {
        a: "world",
        b: 909
    }
]; 



const fns = createFunctions(items); 

const a2: string = fns[0]();  
const b2: string = fns[1](); //Should error - TypeScript should know it's a number

即-我输入的是Foo,但该类型可以是任何类型。

我现在有了这些Foos的列表,该列表可以是所有不同类型的,但是我知道它们的类型。

然后,我想创建一个匹配的功能列表,并对这些功能进行类型强制。

我在这里遇到的问题-这些函数将以具有“ any”类型的返回形式返回。如何执行返回类型?

typescript type-inference
1个回答
1
投票

如果我理解正确,则b中的每个items属性项都可以具有不同的类型。要保留每种类型,可能的解决方案是使用items元组而不是数组,并为mapped tuple声明显式的createFunctions返回类型:

interface Foo<T> { a: string; b: T; }

// we infer the items parameter via generic type parameter as tuple
// a mapped tuple type is used as return type
function createFunctions<T extends readonly Foo<any>[]>(items: T):
    { [K in keyof T]: () => T[K] extends Foo<any> ? T[K]["b"] : never } {
    return items.map(item => () => {
        return item.b;
    }) as any 
    // TS cannot properly infer return type here (generics + conditional types + mapped tuple)
    // alt cast: as unknown as { [K in keyof T]: () => T[K] extends Foo<any> ? T[K]["b"] : never }
}

items元组类型通过const assertions保留:

const items = [
    { a: "hello", b: "foo" },
    { a: "world", b: 909 }
] as const // <--- preserve the tuple type here

const fns = createFunctions(items); // readonly [() => "foo", () => 909]

const a2: string = fns[0](); // works
const b2: string = fns[1](); // error, 909 expected

Playground

Here is an extended Playground that shows inference of multiple generic parameters

© www.soinside.com 2019 - 2024. All rights reserved.