Javascript 是否检查常量类型而不检查加宽类型?

Javascript 是否检查常量类型而不检查加宽类型?,javascript,typescript,Javascript,Typescript,有没有一种方法可以在不扩大类型的情况下对分配给变量的值进行类型检查 比如说, 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"} 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;

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

序言:我没有打字稿中的黑带,所以我的答案可能是次优的(甚至更糟)

constb=((v:T)=>v)(a);
因此,它创建一个匿名函数并立即调用它。如果传递的不是
a
变量,而是文本-它将遵循与直接赋值相同的可赋值规则(例如:文本必须具有完全相同的属性)


缺点:它只进行一次不必要的函数调用,但可能现代引擎可以内联或完全消除它。

我不清楚您到底是如何尝试使用它的,所以也许@zerkms答案正是您想要的,但我突然想到了。我们定义了一个函数,用于检查是否有任何对象具有
foo
属性,该属性是
字符串
。如果函数返回
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
}
consthasfoo=(对象:T):对象是T&THasFoo=>{
返回object.foo的typeof==“string”;
}
常数a={foo:“hi”,bar:42}作为常数;
if(hasFoo(a)){
console.log(a);//a被细化为{readonly foo:“hi”;readonly bar:42;}&THasFoo
}
常数b={foo:“hi”,bar:42};
if(hasFoo(b)){
console.log(b);//b被细化为{foo:string;bar:number;}&THasFoo
}

用例场景是什么?我只能想到这样的东西:
constb=((v:T)=>v)(a)
@zerkms我对常量(typeof a)[“foo”]进行了一些类型提取,结合条件类型,我可以用它做很多事情。到目前为止,我一直在用你的方法将它与lambda结合起来,但实际上它允许我做我不想做的事情。也就是说,
{foo:“hi”,bar:“world”}
不能分配给THasFoo类型的东西,但可以分配给使用Extendes lambdaYep的东西,这是出于设计:我想你需要在问题中更明确一点,我现在可以看到了,但是从第一次看这个问题我看不出来。我非常喜欢这个答案
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
}