typescript 类型脚本联合类型类型推理?

vbkedwbf  于 2023-05-01  发布在  TypeScript
关注(0)|答案(2)|浏览(143)
type TestType = {
    value:string
    run:(v:string)=>void
  }
|
{
  value:string[],
  run:(v:string[])=>void
}
  
var obj:TestType = {
  value:'12',
  run:(val)=>{ // Why is val any? instead of string?
  }
}

我需要value是string然后val是string,value是string[]然后val是string[]

zxlwwiss

zxlwwiss1#

另一种方法是使用泛型类型,用泛型参数的约束替换联合

type TestType<T extends string|string[]> = 
{
    value: T
    run: (v: T) => void
}
  
var obj: TestType<string> = {
  value:'12',
  run:(v)=> { 
  }
}

**编辑:**编译器可以自动推断类型,不需要提供泛型类型,但必须使用辅助函数,如:

type TestType<T extends string|string[]> = 
{
    value: T
    run: (v: T) => void
}

function wrap<T extends string|string[]>( obj: TestType<T>) {
  return obj;
}

var obj = wrap({
  value:'12' as string,
  run:(v)=> { 
  }
});

console.log( obj.value );
obj.run('foo');

在这个例子中,函数被称为wrap。它是通用的,但编译器足够聪明,可以根据提供的参数推断出它的签名。但是请注意,'12'必须转换为string,否则run的参数将被推断为12,而不是string

1zmg4dgp

1zmg4dgp2#

因为TypeScript验证了您提供的(v: any) => void类型的函数实现是否与它被分配给的(v: string) => void类型的变量兼容,这就是这种情况(这就是为什么没有错误)。但这并不会改变内联函数实现的类型。(v: string) => void类型仅适用于调用方:

obj.run(2);  // KO
obj.run('test'); // OK

如果需要在实现中将参数类型设置为string,请显式执行:

var obj: TestType = {
  value: '12',
  run: (val: string) => {
  }
}

如果您只关心编译器错误,则可以禁用noImplicitAny选项。

相关问题