'作为const'结合类型?

发布于 2025-01-31 19:33:41 字数 347 浏览 6 评论 0原文

我想将两个类型的类型结合在一起,并使用它“作为const”将字面类型作为类型:

type MyType = {name: string};

const x:MyType = {
    name: 'test' // Autocompleted, typesafe. But Type is {name: string}, not 
                 // what I want, {name: 'test'}
}

const x = { name: 'test' } as const; // Gives correct type, but no type check...

如何做到这一点?

I want to combine both having a type for a constant, and using it "as const" to get the literal types as the type:

type MyType = {name: string};

const x:MyType = {
    name: 'test' // Autocompleted, typesafe. But Type is {name: string}, not 
                 // what I want, {name: 'test'}
}

const x = { name: 'test' } as const; // Gives correct type, but no type check...

How to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

末蓝 2025-02-07 19:33:41

编辑Sep 2022:

使用Typescript 4.9现在我们可以使用 noreferrer“>满足 操作员:

type MyType = { name: string }

const x ={
  name: 'test', // Autocompleted, typesafe
} as const satisfies MyType

x.name // type is 'test' (not string)

如果出于某种原因,您无法使用满足,那么复制相同的行为很容易:

/**
 * Replacement for TS satisfies operator, until it's well supported
 * Usage:
 * const test = satisfy<{ a: string }>()({ a: 'test', b: 'test' })
 * */
export function satisfy<TSatisfied>(): <T extends TSatisfied>(value: T) => T {
  return (value) => value
}

以前的解决方案:

这是一种实现目标的方法您想要:

type MyType = { name: string }

// This function does nothing. It just helps with typing
const makeMyType = <T extends MyType>(o: T) => o

const x = makeMyType({
  name: 'test', // Autocompleted, typesafe
} as const)

x.name // type is 'test' (not string)

Edit Sep 2022:

With Typescript 4.9 we can now use satisfies operator:

type MyType = { name: string }

const x ={
  name: 'test', // Autocompleted, typesafe
} as const satisfies MyType

x.name // type is 'test' (not string)

And if for some reason, you can't use satisfies, it's fairly easy to replicate the same behavior:

/**
 * Replacement for TS satisfies operator, until it's well supported
 * Usage:
 * const test = satisfy<{ a: string }>()({ a: 'test', b: 'test' })
 * */
export function satisfy<TSatisfied>(): <T extends TSatisfied>(value: T) => T {
  return (value) => value
}

Previous solution:

Here is a way to achieve what you want:

type MyType = { name: string }

// This function does nothing. It just helps with typing
const makeMyType = <T extends MyType>(o: T) => o

const x = makeMyType({
  name: 'test', // Autocompleted, typesafe
} as const)

x.name // type is 'test' (not string)
哥,最终变帅啦 2025-02-07 19:33:41

无需键入检查{name:“ test”}作为const,因为Typescript使用结构性等于{name:“ test”}作为const是MyType的结构相同,因此相同,因此相同。

可以使用这些辅助类型观察到这种行为。

interface MyType {
     name: string;
}
const test = {name: "test"} as const;
type IsEqual<T, U> = [T] extends [U] ? true : false;
type AreTheyEqual = IsEqual<typeof test, MyType> // true they are the same.

任何接受mytype的东西都可以进行类型的测试。

编辑:如果您想强制测试是类型的mytype进行类型检查测试,则无法通过保持字符串字面的字体来做到这一点。

type MyType = {name: string};
const x:MyType = {
    name: 'test' as const
}
type Test = typeof x["name"] // string;

这意味着,如果您想在mytype上同时使用字面和字符串类型,则需要做类似的事情(更改mytype)。注意使用它似乎是详细的,但可以说比“ const”

interface MyType<NAME extends string = string> {
    name: NAME;
}
const x: MyType = {
    name: 'test' // string;
}
const y: MyType<"test"> = {
    name: "test" // "test"
}

type Test1 = typeof x["name"]// string;
type Test = typeof y["name"] // "test";

^ ^ sning和字面类型的样板要少。

There is no need to type-check {name: "test"} as const because Typescript uses structural equality meaning aslong as {name: "test"} as const is the same structure of MyType they will be equal and therefore the same.

This behaviour can be observed using these helper types.

interface MyType {
     name: string;
}
const test = {name: "test"} as const;
type IsEqual<T, U> = [T] extends [U] ? true : false;
type AreTheyEqual = IsEqual<typeof test, MyType> // true they are the same.

Anything that takes a MyType can take a typeof Test.

EDIT: If you want to force test to be of type MyType to type-check test there you cannot do this by keeping the string literal because anything asserted to be MyType will lose the literal type and fall back to string this behaviour can be observed here.

type MyType = {name: string};
const x:MyType = {
    name: 'test' as const
}
type Test = typeof x["name"] // string;

Meaning if you want to have both Literal and string types on MyType you will need to instead do something like this (changing MyType). Note using this seems verbose but is arguably less boilerplate than "as const"

interface MyType<NAME extends string = string> {
    name: NAME;
}
const x: MyType = {
    name: 'test' // string;
}
const y: MyType<"test"> = {
    name: "test" // "test"
}

type Test1 = typeof x["name"]// string;
type Test = typeof y["name"] // "test";

^ Both string and literal types allowed.

孤千羽 2025-02-07 19:33:41

我认为没有任何原始支持。
但是,您可以通过定义另一个使用类型断言来进行打字。

type MyType = {name: string};

const x = {
    name: 'test' 
} as const

const xTypeCheck = typeof (x as MyType) // Check the type of x as MyType 

注意:我使用“ typeof”来避免引用X值的引用,以确保如果没有其他参考,可以删除X的值。

I don’t think there is any primitive support.
But you can do typechecking by defining another const with type assertion.

type MyType = {name: string};

const x = {
    name: 'test' 
} as const

const xTypeCheck = typeof (x as MyType) // Check the type of x as MyType 

Note:I use 'typeof' for avoiding reference of x's value which ensures that x's value can be deleted if there is not any other reference.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文