그것은 기술적으로 구현하기 위해 단위 : 이런
// union of all possible unit types
type UnitType = 'cm' | 'm';
interface UnitConversion<From extends UnitType, To extends UnitType> {
from: From;
to: To;
convert(value: UnitValue<From>): UnitValue<To>;
}
function conversion<From extends UnitType, To extends UnitType>(
from: From, to: To, convert: (value: UnitValue<From>) => UnitValue<To>
): UnitConversion<From, To> {
return { from, to, convert };
}
function identity<T extends UnitType>(t: T): UnitConversion<T, T> {
return { from: t, to: t, convert: v => v };
}
// conversion table for each pair of unit types
const IMPLICIT_CONVERSIONS = {
'cm': {
'cm': identity('cm'),
'm': conversion('cm', 'm', v => new UnitValue(v.value * 0.1, 'm')),
},
'm': {
'cm': conversion('m', 'm', v => new UnitValue(v.value * 10, 'cm')),
'm': identity('m'),
},
};
type ImplicitConversions<
Left extends UnitType,
Right extends UnitType
> = (typeof IMPLICIT_CONVERSIONS)[Left][Right]['to'];
function convert(conversion: UnitConversion<any, any>, value: UnitValue<any>) {
return value.type === conversion.to ? value : conversion.convert(value);
}
type UnitPair<T extends UnitType> = {
left: UnitValue<T>;
right: UnitValue<T>;
};
function convertToCommonType<Left extends UnitType, Right extends UnitType>(
left: UnitValue<Left>,
right: UnitValue<Right>
): UnitPair<ImplicitConversions<Left, Right>> {
const conversion = IMPLICIT_CONVERSIONS[left.type][right.type];
return { left: convert(conversion, left), right: convert(conversion, right) };
}
class UnitValue<Type extends UnitType> {
constructor(
readonly value: number,
readonly type: Type,
) { }
/** Type-safe unit addition */
add<T extends UnitType>(value: UnitValue<T>): UnitValue<ImplicitConversions<Type, T>> {
const { left, right } = convertToCommonType(this, value);
return new UnitValue(left.value + right.value, left.type);
}
}
다음
사용 :
const common = convertToCommonType(
new UnitValue(3, 'cm'),
new UnitValue(10, 'm')
);
// => result type: UnitValue<'m'>
const z = new UnitValue(4, 'cm').add(new UnitValue(5, 'm'));
// => result type: UnitValue<'m'>
그러나, 이것이 너무 많은 복잡성을 야기한다고 주장한다.
새 UnitValue는 어떻게 만듭니 까? 생성자가 있습니까? 아니면 전화해야하는 기능입니까? –
'+'연산자를 사용하여 함께 추가 할 수 있습니까? 그렇게 불행하게도 내가 알고있는 한 Typescript에서 모델링 할 수 없다. –