typescript - 我可以根据全局方法的操作指定 TypeScript 类型约束吗?
问题描述
例如,我可以定义一个字符串类型吗
type BloodPressureMeasurementString = string;
和一个对象类型
type BloodPressureMeasurement = { systolic: number; diastolic: number; }
并指定JSON.parse()
在字符串类型上产生对象类型,反之亦然JSON.stringify()
?
let bp: BloodPressureMeasurement = { systolic: 120, diastolic: 80 };
let bpString = JSON.stringfy(bp); // type of bpString is BloodPressureMeasurementString
let bpCopy = JSON.parse(bpString); // type of bpCopy is BloodPressureMeasurement
目前,这是通过JSON.parse()
/JSON.stringify()
调用站点的类型断言或强制代码完成的。我希望能够将这些移动到创建字符串资源的位置(例如从 Internet 下载时)。
解决方案
有趣的问题!
让我们看看如何安全地做到这一点。
type BloodPressureMeasurementString = string;
type BloodPressureMeasurement = { systolic: number; diastolic: number; }
interface JSON { // extends JSON interface through declaration merging
stringify(val: BloodPressureMeasurement): BloodPressureMeasurementString
parse(val: BloodPressureMeasurementString): BloodPressureMeasurement
}
var a = JSON.stringify({ systolic: 2, diastolic: 3 }); //string
var b = JSON.parse('{"systolic":2,"diastolic":3}'); //BloodPressureMeasurement
var c = JSON.parse('{ "name":"John", "age":30, "city":"New York"}'); //BloodPressureMeasurement!!
并没有真正按预期工作 =/ 你可能已经知道,Typescript 类型系统是结构性的而不是名义上的。BloodPressureMeasurementString
和之间没有任何区别string
。所以我们需要一种模拟名义类型的方法。
让我们通过一些调整来做到这一点1
type BloodPressureMeasurementString = string & {readonly brand: unique symbol};
你有它,a
现在是 type BloodPressureMeasurementString
。
Typescript 足够聪明,可以推断出哪个重载更相关:
但是,请注意,您将无法执行此类操作
var variable: BloodPressureMeasurementString = "some string" //type '"some string"' is not assignable to type 'BloodPressureMeasurementString'
这是意料之中的。您必须使用类型断言。我们可以使用一个函数来帮助我们创建一个 BloodPressureMeasurementString。
//types and values live in separate namespaces so we can have the same name both for the function and for the type
function BloodPressureMeasurementString(str: string) {
return str as BloodPressureMeasurementString
}
然后我们可以做
var variable: BloodPressureMeasurementString = BloodPressureMeasurementString("some string") // OK
1您可能想知道 {readonly brand: unique symbol} 是什么。它的目的是双重的:首先,我们不希望我们的类型与字符串混淆,我们也不希望它与相似的类型混淆。我们不能写出结果永远不会的字符串和数字,如果我们写成 string & { },它会与字符串混淆,如果我们写 string & { brand: symbol },另一个类似的类型(命名不同但有字符串& { brand: symbol }) 可能与我们的类型混淆。唯一的(需要只读)将不允许这样做。
推荐阅读
- oracle - 如何在oracle中指定要写入一个csv文件的最大行数?
- javascript - 获取 Geopoint 时打字稿错误,意外的“,”
- nativescript - VideoPlayer 高度适合内容/无黑条
- python - 计算线性回归线周围的置信区间
- ios - 选择为 UISegmentedControl 选择哪种情况
- c# - 扫描对象列表并比较对象值
- r - ggplot 直方图作为特定组的百分比
- excel - 如何修复此 SlicerCache 对象错误?
- visual-studio - Azure Devops 构建失败警告 MSB3245:无法解析此引用
- java - 为什么 Java BigInteger 说“可能是素数”而不是“肯定是素数”?