Typescript 是否有“部分”的打字脚本<;任何>;`输入函数参数以接受'any',但不接受'void'?

Typescript 是否有“部分”的打字脚本<;任何>;`输入函数参数以接受'any',但不接受'void'?,typescript,types,Typescript,Types,对于接口,可以使用Partial,表示“允许X的所有属性,但不期望它们中的任何一个” 因此,以下情况会导致编译器错误: interface X { foo: boolean } function doSomething(x: Partial<X>) { let aBoolean: boolean = x.foo; // ERROR: possibly undefined } doSomething({ foo: true }); // OK doSomething({});

对于接口,可以使用
Partial
,表示“允许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>'
我希望我的函数接受任何东西作为参数,但是在函数内部,如果不先检查对象的属性,我就不能访问它们。即使在函数
x
中有type
void
never
也可以

我并不惊讶
Partial
没有按我所希望的方式工作-我绝对不是在问“为什么
Partial
没有按我所希望的方式工作”。我在问:

对于参数
x
我可以使用什么类型:

  • 它接受任何/每种类型的参数
  • 在函数内部,
    x
    的类型可能是每个属性都未定义的类型(或者
    x
    的类型为
    void
    ,等等)
  • 我可以为参数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'
    }
    
    函数doSomething(x?:{}){
    //设b:boolean=x;//错误
    //设o:{}=x;//StrictNull在上签入时出错
    //let bar:string=x.foo;//错误
    如果(x的类型=='boolean'){
    设b:boolean=x;
    }
    如果(x!==未定义){
    if(hasProperty(ofTypeString,x,'foo')){
    let bar:string=x.foo;
    }
    }
    };
    函数属性(
    守卫:(p:any)=>p是T,
    x:{},
    姓名:N
    ):x是{[n in n]:T}
    {
    return(x中的名称)和guard(x作为任何名称)[名称];
    }
    TypeString的函数(p:any):p是字符串{
    返回类型p==='string'
    }
    
    只需将
    x
    设置为可选?执行
    操作时不会出现错误!!x、 foo
    在该示例中,或者如果您将其更改为
    {let bar:string=x.foo;}
    。我遗漏了什么吗?关键是在函数中无法保证
    x
    具有什么属性,我希望类型能够反映这一点。
    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'
    }