作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我只是好奇,有没有办法在 TypeScript 中区分原子类型以提高类型安全性?
换句话说,有没有办法复制下面的行为:
export type Kilos<T> = T & { discriminator: Kilos<T> }; // or something else
export type Pounds<T> = T & { discriminator: Pounds<T> }; // or something else
export interface MetricWeight {
value: Kilos<number>
}
export interface ImperialWeight {
value: Pounds<number>
}
const wm: MetricWeight = { value: 0 as Kilos<number> }
const wi: ImperialWeight = { value: 0 as Pounds<number> }
wm.value = wi.value; // Should give compiler error
wi.value = wi.value * 2; // Shouldn't error, but it's ok if it would, because it would require type casting which asks for additional attention
wm.value = wi.value * 2; // Already errors
const we: MetricWeight = { value: 0 } // Already errors
或者可以将它放在一个容器中的东西:
export type Discriminate<T> = ...
export type Kilos<T> = Discriminate<Kilos<T>>;
export type Pounds<T> = Discriminate<Pounds<T>>;
...
编辑
export type Kilos<T> = T & { discriminator: any extends infer O | any ? O : never };
export type Pounds<T> = T & { discriminator: any extends infer O | any ? O : never };
export interface MetricWeight {
value: Kilos<number>
}
export interface ImperialWeight {
value: Pounds<number>
}
const wm: MetricWeight = { value: 0 as Kilos<number> }
const wi: ImperialWeight = { value: 0 as Pounds<number> }
wm.value = wi.value; // Errors, good
wi.value = wi.value * 2; // Errors, but it's +/- ok
wi.value = wi.value * 2 as Pounds<number>; // Shouldn't error, good
wm.value = wi.value * 2; // Errors, good
const we: MetricWeight = { value: 0 } // Errors, good
不幸的是,以下方法不起作用:
export type Discriminator<T> = T & { discriminator: any extends infer O | any ? O : never }
export type Kilos<T> = Discriminator<T>;
export type Pounds<T> = Discriminator<T>;
export interface MetricWeight {
value: Kilos<number>
}
export interface ImperialWeight {
value: Pounds<number>
}
const wm: MetricWeight = { value: 0 as Kilos<number> }
const wi: ImperialWeight = { value: 0 as Pounds<number> }
wm.value = wi.value; // Doesn't error, this is bad
wi.value = wi.value * 2; // Errors, but it's +/- ok
wi.value = wi.value * 2 as Pounds<number>; // Shouldn't error, good
wm.value = wi.value * 2; // Errors, good
const we: MetricWeight = { value: 0 } // Errors, good
编辑
export type Kilos<T> = T & { readonly discriminator: unique symbol };
export type Pounds<T> = T & { readonly discriminator: unique symbol };
...
但是仍然存在缺乏的问题
export type Discriminator<T> = ...
有什么想法可以让它更干净吗?由于类型别名使两个类型引用都坚持鉴别器......
export type Kilos<T> = T & { readonly '': unique symbol };
export type Pounds<T> = T & { readonly '': unique symbol };
这有助于解决 IDE 的智能感知污染
最佳答案
只需将其定义为:
const marker = Symbol();
export type Kilos = number & { [marker]?: 'kilos' };
export const Kilos = (value = 0) => value as Kilos;
export type Pounds = number & { [marker]?: 'pounds' };
export const Pounds = (value = 0) => value as Pounds;
然后磅和公斤自动转换为数字和数字,但不是相互转换。
let kilos = Kilos(0);
let pounds = Pounds(0);
let wrong: Pounds = Kilos(20); // Error: Type 'Kilos' is not assignable to type 'Pounds'.
kilos = 10; // OK
pounds = 20; // OK
let kilos2 = 20 as Kilos; // OK
let kilos3: Kilos = 30; // OK
pounds = kilos; // Error: Type 'Kilos' is not assignable to type 'Pounds'.
kilos = pounds; // Error: Type 'Pounds' is not assignable to type 'Kilos'.
kilos = Kilos(pounds / 2); // OK
pounds = Pounds(kilos * 2); // OK
kilos = Pounds(pounds / 2); // Error: Type 'Pounds' is not assignable to type 'Kilos'.
kilos = pounds / 2; // OK
pounds = kilos * 2; // OK
如果您想防止从“增强”单位自动转换为“普通”数字,则只需从标记字段中删除可选:
const marker = Symbol();
export type Kilos = number & { [marker]: 'kilos' };
// ------------------------------------^ -?
export const Kilos = (value = 0) => value as Kilos;
// then:
const kilos = Kilos(2); // OK
kilos = 2; // Error
kilos = kilos * 2; // Error
关于typescript - TypeScript 中的原子类型区分(名义原子类型),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56199492/
我正在尝试比较一系列元素的两种不同分类。假设我想获得这样的图形: 通过以下 iPython session 获得: In [1]: df Out[1]: Index: 446 entries, el
我想在 Google Charts 的轴标签上使用文本标签而不是数字标签。如何存档?结果应如下所示(气泡图示例): 我在 stackoverflow 的某个地方找到了这个例子,但现在我找不到了。不管怎
我是一名优秀的程序员,十分优秀!