Types

Structural Typing

Example


type A = {
	a: string
}

type B = {
	a: '4',
	b: string
}

{
	const invalid: B = {
		a: 'Hello'
	}
	const validA: A = {
		a: 'Hello'
	}
	const validAorB: A | B = {
		a: 'Hello'
	}

	const invalidAandB: A & B = {
		a: '4'
	}
	const validAandB: A & B = {
		a: '4',
		b: 'hello',
	}
}

// Downcast
{
	const invalid: A  = {
		a: 'Valid so far',
		b: 'Failure here',
	} 
	const valid: A = {
		a: 'Valid so far',
		b: 'Failure here'
	} as A
}

// Fns
{
	const value: B  = {
		a: '4',
		b: 'stringValue',
	} 

	const validDowncast: A = ((a: A) => a)(value)
	const invalidCopy: B = ((a: A) => a)(value)
	const validExtends: B = (<X extends A>(a: X) => a)(value)
}

Nominal Typing

Example

{
	class Regex {
		type = 'regex'
		value: string
		constructor(value: string) {
			this.value = value
		} 
	}
	
	class Url {

		type = 'url'
		value: string
		constructor(value: string) {
			this.value = value
		} 
	}
	
	
	// Same nominal again
	{
		const invalid: Url = {
			value: 'http://google.com'
		}
		const validA: Regex = {
			value: 'Hello'
		}
		const validAorB: Regex | Url = {
			value: 'Hello'
		}
	
		const invalidAandB: Regex & Url = {
			value: 'http://google.com'
		}
		const validAandB: Regex & Url = {
			value: 'http://google.com'
		}
	}

	
	// Structural still gets moved around like Nominal
	{
		const shouldBeInvalid: Url = new Regex('http://google.com')
		const validA: Regex = new Url('http://google.com')
	}


	
	// Casting
	{
		const invalid: Url  = new Url('http://google.com')
		const valid: Url = {
			value: 'Valid so far',
		} as Url
	}
	
	// Fns
	{
		const value: Url  = new Url('http://google.com')
	
		const validDowncast: Regex = ((a: Regex) => a)(value)
		const invalidCopy: Url = ((a: Regex) => a)(value)
		const validExtends: Url = (<X extends Regex>(a: X) => a)(value)
	}
	
}

Sum Types

Opaque Types

Example


class In<T> {
private "____ in": T;
}

type Seconds = number & In<"s">;

type Milliseconds = number & In<"ms">;
interface DateConstructor {
	now(): Milliseconds;
}

{
  const now: Milliseconds = Date.now();

  function toSeconds(ms: Milliseconds) {
	  return ms / 1000.0 as Seconds
  }

  const nowSeconds: Seconds = toSeconds(now)

//   const nowSeconds: Seconds = toSeconds(now)
}

Dependent Types

Linear Types (ownership)

deck

By Justin Miller

deck

  • 16