首页 > 其他分享 >[Typescript] Branded type

[Typescript] Branded type

时间:2022-12-24 19:37:00浏览次数:48  
标签:123 USD const string Typescript str Branded type

For example, we have a type repersent currency: USD, value should be something like '$123', a string type with `$` and number.

 

So let's say we make a USD type as string

type USD = string

PORS: it is semantice

CONDs: I can give any value doesn't match the requiremenets of USD

for example: '#123'

 

To solve this problem we can use Branded type.

 

Define a Branded type

declare const brand: unique symbol;
type Brand<K, T> = T & {[brand]: K}

Now a branded USD type should be

type USD = Brand<'USD', string>
/*
string & {
  brand: 'USD'
}
*/

Now if we assign correct value to a branded USD type, we found it has error:

// @ts-expect-error
const price: USD = '$123' // '$123' is not assignable to USD

 

Use Branded type with Type guards and Type assertions

declare const brand: unique symbol;
type Brand<K, T> = T & {[brand]: K}

type USD = Brand<'USD', string>
function isUSD(str: string | USD): str is USD {
  return typeof str === 'string' && str.toString().startsWith('$') && !Number.isNaN(+str.substring(1))
}
function assertUSD(str: string | USD): asserts str is USD {
  const b = typeof str === 'string' && str.toString().startsWith('$') && !Number.isNaN(+str.substring(1))
  if(!b) {
    throw new Error('Not a USD currency')
  }
}

Usage with type guards:

const priceUSD = '$123'
const priceEUR = '€123'

function getUSDPayment(usd: USD) {
  console.log(usd)
}

// OK
if (isUSD(priceUSD)) {
 getUSDPayment(priceUSD)
}

// NOT
if (isUSD(priceEUR)) {
 getUSDPayment(priceEUR)
}

Usage with type assertion:

const priceUSD = '$123'
const priceEUR = '€123'

function payByUSD(usd: string) {
  assertUSD(usd)
  getUSDPayment(usd)
}

function getUSDPayment(usd: USD) {
  console.log(usd)
}

payByUSD(priceUSD)
payByUSD(priceEUR) // throw error

 

Resources:

Surviving the TypeScript Ecosystem — Part 6: Branding and Type-Tagging

Branded Types give you stronger input validation

https://github.com/kevinbgreene/typescript-demo/blob/branding/src/index.ts

 

标签:123,USD,const,string,Typescript,str,Branded,type
From: https://www.cnblogs.com/Answer1215/p/17003243.html

相关文章