首页 > 解决方案 > 键入不带任何内容的“类型谓词”

问题描述

我在尝试正确键入我的一个函数时遇到问题。在下面的代码中,是的类型,xany想比它更好地键入它。

interface Pet {
  name: string;
}

const checkType = (x: any): x is Pet => {
  return 'name' in x && typeof x.name === 'string';
}

我认为unknown或者object最适合,但两者都给我一个错误

interface Pet {
  name: string;
}

const checkType = (x: unknown): x is Pet => {
  return 'name' in x && typeof x.name === 'string';
}

对象的类型为“未知”

interface Pet {
  name: string;
}

const checkType = (x: object): x is Pet => {
  return 'name' in x && typeof x.name === 'string';
}

“对象”类型上不存在属性“名称”


所以我的问题是,如何在x不强制转换的情况下正确输入any



以下可能是一个解决方案,但我发现它太多且具体:

操场

interface Pet {
  name: string;
}

const checkType = (x: object): x is Pet => {
  return 'name' in x && typeof (x as {
    name: unknown,
  }).name === 'string';
}

更多信息:

示例any可能会导致问题:

在此处输入图像描述

标签: typescripttypescript-typings

解决方案


我会使用部分 Pet 接口作为类型保护的输入。

type maybePet = Partial<Pet>

const checkType = (x: maybePet): x is Pet => {
  return 'name' in x && typeof x["name"] === 'string';
}

这允许编译器标记非类似对象的输入,例如数字。

let a = {}; 
if(checkType(a))//allows the type check but will not pass
{
  console.log("a")
} 

let b = {name:"good", other:1}; 
if(checkType(b))//allows the type check and passes
{
  console.log("b")
} 
checkType(3) //typescript complier complains

我的示例代码有点做作,如果您更改要检查的对象的键,使其与 Pet 的接口不匹配,编译器会抱怨,因为它推断您的对象不能是 Pet 类型,但是如果您正在接收任何对象(或显式将其转换为任何对象),则可以继续检查。

let c = {namey:"good", other:1}; 
if(checkType(c))//compiler complains because it knows typeof c can't be a Pet
{
  console.log("c")
} 

let d:any = {namey:"good", other:1}; 
if(checkType(d))//allows the type check but will not pass
{
  console.log("d")
} 

游乐场链接


推荐阅读