无法获得通用的联合打字?

时间:2019-04-27 16:21:30

标签: typescript typescript-typings

所以这是我正在使用的一些代码。 我似乎无法使其正常工作。

type someGeneric<T> = { a: T, b: (args: T) => void };

type abc = someGeneric<string> | someGeneric<number>;
type xyz = someGeneric<string | number>;
type someType = ? ;

const abc: abc = { a: 'someString', b: (args) => { } }; // args inferred as any;
const xyz: xyz = { a: 'someString', b: (args) => { } } // args inferred as string | number;

const someType: someType = { a: 'someString', b: (args) => { } }// args need to be inferred as string;

我不确定如何使该功能正常运行。 对此的任何帮助将不胜感激。

谢谢。

1 个答案:

答案 0 :(得分:1)

在第一种情况下,abc不能推断为args的类型,因为它可以是数字或字符串,但不能是string | number。只要允许与a匹配的值即可。

let validString: abc = {a:'someString', b: (args: string) => {} };
let validNumber: abc = {a: 1, b: (args: number) => {}};

let notValidabc: abc = {a: 1, b: (args: string)=> {}}; // this isn't allowed because a and args have to be both number or both string
let isvalidxyz:  xyz = {a: 1, b: (args: string)=> {}}; // this is allowed

没有一种创建类型为“根据分配给它的类型推断通用类型”的类型的方法(正如我真正希望的那样),但是您可以编写一个非常简单的包装函数,以便约束在参数类型和填充中指定以推断泛型:

function makeThing<T>(thing: someGeneric<T>){
    return thing;
}

const thing = makeThing({a: 'somestring', b:(args)=>{}});
// args is inferred as string, thing is inferred as someGeneric<string>

尝试使用this case,但将noImplicitAny标志设置为true,您会发现不是推断为args ,而是打字稿不能推断args的类型。

const abc: abc = { a: 'someString', b: (args) => { } };

Typescript仅在给定约束的类型只有一个选项的情况下才能推断类型,在这种情况下,约束为(arg: string)=>any(arg: number)=>any,因为有2个选项(并且可以请勿使用string | number,因为那也不成立(1)) 它无法推断出它是什么。

在另一种有函数的情况下,打字稿试图根据给定的字段定义通用T,发现a与字符串匹配,因此将其用作T,然后尝试推断类型arg基于T为字符串。

(1):string | numberarg无效,因为整个对象在给定时间只能符合someGeneric<string>someGeneric<number>,无论哪种情况{{1 }}无效。