简体   繁体   English

未知的 Typescript 属性类型保护

[英]Typescript property type guards on unknown

I'm trying to type guard an unknown type我正在尝试输入保护未知类型

const foo  = (obj: unknown) => {
    if (typeof obj === 'object' && obj) {
        if ('foo' in obj && typeof obj.foo === 'string') {
            return obj.foo;
        }
    }
};

But I'm getting 但我得到

Property 'foo' does not exist on type 'object'. “对象”类型上不存在属性“foo”。

I also tried with is expression does not work:我也试过 is 表达式不起作用:

const foo  = (obj: unknown): obj is { foo: 'string' } => {
    if (typeof obj === 'object' && obj) {
        if ('foo' in obj && typeof obj.foo === 'string') {
            return obj;
        }
    }
    throw new Error();
};

Please consider using this helper:请考虑使用这个助手:

const hasProperty = <Obj, Prop extends string>(obj: Obj, prop: Prop)
  : obj is Obj & Record<Prop, unknown> =>
  Object.prototype.hasOwnProperty.call(obj, prop);

in your case.在你的情况下。 in operator works as expected mostly with unions. in操作符主要与工会一起按预期工作。 Please see here , here and here请看这里这里这里

Working solution:工作解决方案:

const hasProperty = <Obj, Prop extends string>(obj: Obj, prop: Prop)
  : obj is Obj & Record<Prop, unknown> =>
  Object.prototype.hasOwnProperty.call(obj, prop);

const foo = (obj: unknown) => {
  if (typeof obj === 'object' && obj) {
    if (hasProperty(obj, 'foo') && typeof obj.foo === 'string') {
      return obj.foo;
    }
  }
};

Playground 操场

However, since you want to throw an error if obj is invalid, you can use assert function :但是,由于您想在obj无效时抛出错误,因此可以使用assert function

const hasProperty = <Obj, Prop extends string>(obj: Obj, prop: Prop)
  : obj is Obj & Record<Prop, unknown> =>
  Object.prototype.hasOwnProperty.call(obj, prop);

function foo(obj: unknown): asserts obj is { foo: string } {
  const isValid =
    typeof obj === 'object' &&
    obj &&
    hasProperty(obj, 'foo') &&
    typeof obj.foo === 'string';

  if (!isValid) {
    throw new Error();
  }

};

declare var obj: unknown;

foo(obj);

obj.foo // ok

Playground 操场

You're going to have to give TypeScript a little help here:你将不得不在这里给 TypeScript 一些帮助:

type fooObj = object & { foo: unknown };
const foo = (obj: unknown) => {
    if (typeof obj === 'object' && obj) {
        if ('foo' in obj && typeof (obj as fooObj).foo === 'string') {
            return (obj as fooObj).foo;
        }
    }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM