【问题标题】:Is there a TypeScript `Partial<any>` type for a function parameter to accept `any` but be `void`?函数参数是否存在 TypeScript `Partial<any>` 类型以接受 `any` 但为 `void`?
【发布时间】:2023-03-13 19:10:01
【问题描述】:

对于一个接口,可以使用Partial&lt;X&gt;Mapped Type 来表示“允许 X 的所有属性,但不要期望它们”。

这样会导致以下编译错误:

interface X { foo: boolean }

function doSomething(x: Partial<X>) {
  let aBoolean: boolean = x.foo; // ERROR: possibly undefined
}

doSomething({ foo: true }); // OK
doSomething({}); // OK
doSomething(true); // ERROR: Type 'boolean' has no properties in common with 'Partial<X>'

我想对any 做同样的事情,说“这个函数可以接受任何东西作为参数,但你不能指望那里有任何东西”

function doSomething(x: Partial<any>) {
  let aBoolean: boolean = x.foo; // OK, but I wish it wasn't
}

doSomething({ foo: true }); // OK
doSomething({}); // OK
doSomething(true); // OK
doSomething(/* etc. */); // OK

我希望我的函数接受任何东西作为参数,但在函数内部,如果不先检查它们,我应该无法访问对象的任何属性。如果函数内部x 的类型为voidnever,也可以。

我并不惊讶 Partial&lt;any&gt; 没有按我希望的方式工作 - 我绝对不会问“为什么 Partial&lt;any&gt; 不能按我希望的方式工作”。我在问:

我可以为参数x 使用什么类型,这样:

  1. 它接受任何/每种类型的参数
  2. 在函数内部,x 的类型可能每个属性都未定义(或者 x 的类型为 void 等)

【问题讨论】:

  • 只是将x 设为可选? TS playground
  • 在该示例中执行 !!x.foo 或将其更改为 { let bar: string = x.foo; } 时没有错误。我错过了什么吗?
  • 关键是在函数中不能保证x 有什么属性,我希望类型能够反映这一点。

标签: typescript types


【解决方案1】:

我可以为参数 x 使用什么类型,这样:

1. it accepts arguments of any/every type
2. inside the function the type of x is something where every property 
   is possibly undefined (or x is of type void, etc.)

它是空对象类型{},它几乎兼容任何类型,并允许您将几乎任何东西传递给doSomething

function doSomething(x?: {})  {...}

doSomething({ foo: true }); // OK
doSomething({}); // OK
doSomething(true); // OK
doSomething(/* etc. */); // OK

但在实现中对此一无所知,不先检查就无法使用:

function doSomething(x?: {})  {
    //let b: boolean = x; // error
    //let o: {} = x; // error when strictNullChecks in on
    //let bar: string = x.foo;  // error

    if (typeof x === 'boolean') {
        let b: boolean = x;
    }
    if (x !== undefined) {
        if (hasProperty(ofTypeString, x, 'foo')) {
            let bar: string = x.foo;
        }
    }
};

function hasProperty<T, N extends string>(
    guard: (p: any) => p is T, 
    x: {}, 
    name: N
): x is {[n in N]: T} 
{
    return (name in x) && guard((x as any)[name]);
}


function ofTypeString(p: any): p is string {
    return typeof p === 'string'
}

【讨论】:

    猜你喜欢
    • 2019-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 2019-03-14
    • 2021-08-24
    • 1970-01-01
    • 2019-01-09
    相关资源
    最近更新 更多