typescript 是否检查没有加宽类型的常量类型?

olhwl3o2  于 2023-01-06  发布在  TypeScript
关注(0)|答案(3)|浏览(127)

有没有一种方法可以在不扩大类型的情况下对赋给变量的值进行类型检查?
例如,

const a = {foo: "hi"} as const; // typeof = {foo: "hi"}

type THasFoo = {foo: string};
const b: THasFoo = {foo: "hi"} as const; // typeof = THasFoo

我想检查一下我给a赋值的东西是否有成员foo,但不会丢失该值的类型信息。
注意:我特别感兴趣的是来自直接赋值的检查类型。

const a = {foo: "hi", bar: "world"} as const;

type THasFoo = {foo: string};
const b: THasFoo = a;

及格。不过,

type THasFoo = {foo: string};
const b: THasFoo = {foo: "hi", bar: "world"} as const;

没有。这是我想要的后一种检查形式(但不会扩大)。

ddrv8njm

ddrv8njm1#

前言:我没有TypeScript黑带,所以我的答案可能是次优的(甚至更糟)

const b = (<T extends THasFoo>(v: T) => v)(a);

因此,它创建了一个匿名函数并立即调用它。如果传递的不是a变量,而是文本-它将遵循相同的赋值规则(例如:文字必须具有完全相同的属性),就好像它是直接赋值一样。
缺点:它会产生一个不必要的函数调用,但现代引擎可能会内联或完全消除它。

fquxozlt

fquxozlt2#

我不清楚你到底想怎么用这个,所以也许@zerkms的答案就是你要找的,但是我的想法跳到了type guards上,我们定义了一个函数来检查任何对象是否有foo属性string,如果函数返回true,那么typescript就把类型缩小到包括THasFoo,而不扩大任何内容。

const hasFoo = <T extends {foo?: any}>(object: T): object is T & THasFoo => {
    return typeof object.foo === "string";
}

const a = {foo: "hi", bar: 42} as const;
if (hasFoo(a)) {
    console.log(a); // a gets refined to { readonly foo: "hi"; readonly bar: 42; } & THasFoo
}

const b = {foo: "hi", bar: 42};
if (hasFoo(b)) {
    console.log(b); // b gets refined to { foo: string; bar: number; } & THasFoo
}

Playground Link

dxxyhpgq

dxxyhpgq3#

您得到的错误是由于过多的属性造成的。您可以使用suppressExcessPropertyErrors标志禁用此检查。
Playground:禁用抑制过量属性错误
Playground:禁止出现过量属性错误

相关问题