类型对象包括字符串?

Type Object includes string?

function isObject(v: any): v is Object{ 
    return v instanceof Object && !Array.isArray(v);
}


let v: string | Object;
if (isObject(v))
    v.hasOwnProperty("x");
else
if (typeof v === 'string')
    v.trim();             //Error: Property 'trim' does not exist on type 'never'

我对最后一行中的那个错误感到困惑,显然,v 被缩小为键入“never”,但我看不到它的逻辑。 (打字稿版本 4.2.3)

let v: string | Object;

在执行 instanceOf(类型检查器)时将 v 变量类型视为 string 因为您提到字符串是第一种类型,而 Object 是该变量的第二种类型。因此,在这种情况下,如果没有该变量的任何值,instanceOf 如何知道类型?所以它会检查null instanceof Object。这意味着 null 不是对象类型。这就是为什么 isObject() return 错误的原因。参见

console.log(null instanceof Object)

If you assign any value, then only the instanceOf will be considered the type based on value because of that variable have two data types.

这是Object接口在打字稿中定义的方式:

interface Object {
    constructor: Function;
    toString(): string;
    toLocaleString(): string;
    valueOf(): Object;
    hasOwnProperty(v: PropertyKey): boolean;
    isPrototypeOf(v: Object): boolean;
    propertyIsEnumerable(v: PropertyKey): boolean;
}

几乎任何类型,包括像 string 这样的基元,都可以分配给 Object(是的,字符串具有上述所有属性)。

object(小写)是一种表示非原始类型的类型,即任何不是 numberstringboolean、[=18 的类型=]、nullundefined

function isObject(v: any): v is object {
    return v instanceof Object && !Array.isArray(v);
}

declare let v: string | object;
if (isObject(v))
    v.hasOwnProperty("x");
else
    v.trim(); // v narrowed to string

Playground

Do's and Don'ts

我认为这种看似奇怪的行为的解释是object != Object。而 object 是一种表示所有非基本类型(不是字符串)的类型,而 Object 类型只是一个接口,包含围绕 javascript 对象的通用方法,如 toString() 等

在函数签名中有:

v is Object

这只会检查您的变量类型是否实现了 Object 接口的所有方法。实际上对于 string,情况就是这样,因此 Typescript 认为:

等等,他给我提供了一个 Objectstring 的变量,它们都实现了 Object 接口,因此该方法将 return每次都是真的。这就是为什么在 if.

的 else 情况下它是 never

如果您使用 object 而不是 Object,这将得到解决,因为 object 是一种代表所有非基本类型的类型(不是 string)。因此,typescript 不会像 Object.

那样认为你的函数会一直 return true
const a: Object = '1'; // OK
const b: Object = 1; // OK
const c: Object = false; // OK
const d: Object = {}; // OK
const e: Object = undefined; // Error
const f: Object = null; // Error

const g: object = '1'; // Error
type T1 = string extends Object ? boolean : number; // boolean
type T2 = Number extends Object ? boolean : number; // boolean
...
type T3 = undefined extends Object ? boolean : number; // number
type T4 = null extends Object ? boolean : number; // number

也就是说,Object是ONLY成员定义的类型。 并且每个类型都扩展了 Object 除了 undefined 和 null

所以

v is Object ===> v is object