我的问题是是否可以使用 typeof 来推断 const 变量的实际类型,而与定义的更广泛的类型无关?
如果您假设嵌套对象看起来像一棵树并且简单的属性是叶子。然后我想有一个方法来定义子树。
我想在使用 in keyof
的泛型中使用它,并且只想迭代明确提到的键而不是类型定义的所有隐含键。在下面的示例中,我需要 keyof typeof a
不包含 bar
或 baz
。
这个想法是 Base
类型旨在定义变量 a
的“最大扩展”的可能结构,并允许在编写 a
时使用自动完成。
一旦定义了 a
,它就有了自己的更窄类型,我想稍后使用它来过滤某些键。
type Base = {
foo?: string;
bar?: string;
baz?: string;
}
const a: Base = {
foo: '123',
};
const a_typeof: typeof a = {
foo: '123',
bar: '123', // I want this to be wrong
};
我明白,由于我将 a
定义为 Base
类型,因此它们等于 type of a == Base
,但我希望 typeof a = { foo: string }
和 { foo: string }
类型更窄的基地。
特别是,如果我从 : Base
的定义中删除 a
,我会得到想要的效果。
const b = {
foo: '123',
};
const b_typeof: typeof b = {
foo: '123',
bar: '123',
// ^: Type '{ foo: string; bar: string; }' is not assignable to type '{ foo: string; }'
};
答案 0 :(得分:1)
让我们从编译器的角度仔细看看你要做什么:
你告诉它 a
是 Base
类型以获得自动完成作为副作用。
然后告诉它 b
与 a
具有相同的类型,即 Base
。
然后你试着告诉它 b
也 和 a
的 value 具有相同的类型。< /p>
a
的值的类型是 { foo: string; }
,即使 TypeScript 允许您这样做,也意味着 foo
是必需的和可选的。就类型系统而言,这是无稽之谈。
现在,假设您决心绕过上述规定。您可以使用泛型函数来完成此操作,该函数返回您希望自动完成的值的受限 版本:
const getA = <K extends Base>(a: K) => a;
const a = getA({ foo: "123" });
const a_typeof: typeof a = {
foo: '123',
bar: '123', //Error: 'bar' does not exist in type 'Pick<Base, "foo">'
};
泛型类型参数确保自动完成,而 Pick
实用程序类型过滤返回的类型。尽管您会得到一个您想要的错误,但没有什么可以阻止您传递,例如,Base
到泛型类型参数以消除错误。
回答问题“是否可以使用 typeof
来推断 const 变量的实际类型,而与定义的更广泛的类型无关?” - 不,这是不可能的。如果您明确指定了更宽的类型,则无论赋值如何都会使用它。