简体   繁体   English

TypeScript 中的非破坏性类型断言

[英]Non-Destructive Type Assertions in TypeScript

I am looking for a good way of constraining a literal value in TypeScript to certain type without loosing inferred type information.我正在寻找一种在不丢失推断类型信息的情况下将 TypeScript 中的文字值限制为特定类型的好方法。

Let's consider a type Named that is guaranteed to have a name.让我们考虑一个Named类型,它保证有一个名字。

type Named = {
  name: string
};

Using a type annotation creates an error for the extra field born in the literal used to define the const cat1 .使用类型注释创建额外字段错误born在用于定义常量字面cat1

const cat1: Named = {
  name: 'Findus',
  born: 1984,  // this is an error
};
const name1 = cat1.name;
const born1 = cat1.born;  // this is an error

By using a typecast I can define the const cat2 but it looses type information for the field born which creates a problem while trying to access that field later on.通过使用类型转换,我可以定义常量cat2 ,但它失去字段类型信息born ,同时试图访问该字段以后这将创建一个问题。

const cat2 = {
  name: 'Findus',
  born: 1984,
} as Named;
const name2 = cat2.name;
const born2 = cat2.born;  // this is an error

One way to solve the problem is to use an IIFE to type check the literal while defining the const cat3 .解决该问题的一种方法是在定义 const cat3时使用 IIFE 对文字进行类型检查。

const cat3 = (<C extends Named>(c: C) => c)({
  name: 'Findus',
  born: 1984,
});
const name3 = cat3.name;
const born3 = cat3.born;

Is this the intended way of doing the constraining, or are there better alternative ways of writing compatible code?这是进行约束的预期方式,还是有更好的替代方法来编写兼容代码?

Simply say that your type is a record with one required parameter name简单地说,您的类型是具有一个必需参数名称的记录

interface Named extends Record<string, any> {
    name: string
}

Or you can use something like this或者你可以使用这样的东西

type Named<T> = T & {
    name: string
}


const a: Named<{ surname: string } > = {
    name: 'hello',
    surname: 'world'
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM