Skip to content

Commit

Permalink
feat(Typescript): Add a more convienient single-type type guard
Browse files Browse the repository at this point in the history
  • Loading branch information
nokome committed Jul 31, 2019
1 parent 1b234f5 commit 0e59220
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 3 deletions.
28 changes: 27 additions & 1 deletion ts/util/__tests__/guards.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
isInlineEntity,
isPrimitive,
typeIs,
nodeIs
nodeIs,
isa
} from '../guards'

const primitives = [null, true, false, NaN, 2, 'string']
Expand Down Expand Up @@ -55,6 +56,31 @@ describe('nodeIs', () => {
expect(nodeIs(typeMap)({ type: typeMap.someType })).toBe(true))
})

describe('isa', () => {
const person = { type: 'Person' }
const para = { type: 'Paragraph', content: [] }

test('it returns false for undefined types', () => {
// This is a compile error too
// @ts-ignore
expect(isa(person, 'Foo')).toBe(false)
})

test('it returns true for the right type', () => {
expect(isa(person, 'Person')).toBe(true)
expect(isa(para, 'Paragraph')).toBe(true)
})

test('it returns false for the wrong type', () => {
expect(isa(para, 'Person')).toBe(false)
expect(isa(null, 'Person')).toBe(false)
expect(isa(true, 'Person')).toBe(false)
expect(isa(1.0, 'Person')).toBe(false)
expect(isa([], 'Person')).toBe(false)
expect(isa({ type: 'Foo' }, 'Person')).toBe(false)
})
})

describe('isPrimitive', () => {
test('returns true for primitive values', () => {
primitives.map(node => expect(isPrimitive(node)).toBe(true))
Expand Down
19 changes: 17 additions & 2 deletions ts/util/guards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import {
InlineContent,
ListItem,
Node,
Paragraph
Paragraph,
Types
} from '../types'
import { TypeMap, TypeMapGeneric } from './type-map'
import {
Expand Down Expand Up @@ -52,7 +53,7 @@ export const nodeIs = <T extends Partial<TypeMap | TypeMapGeneric>>(
* Returns a boolean value and narrows the TypeScript inferred type to
* the type.
*
* @param type The type to test the
* @param type The type to test for
*/
// eslint-disable-next-line
export const is = <Ts extends Entity>(type: keyof TypeMap<Ts>) => {
Expand All @@ -63,6 +64,20 @@ export const is = <Ts extends Entity>(type: keyof TypeMap<Ts>) => {
return nodeIs(typeMap)
}

/**
* A type guard to determine whether a node is of a particular type.
* Returns a boolean value and narrows the TypeScript inferred type to
* the type.
*
* @param type The type to test for
*/
export const isa = <K extends keyof Types>(
node: Node,
type: K
): node is Types[K] => {
return isEntity(node) && node.type === type
}

/**
* Type guard to determine whether a node is a primitive type.
* Returns a boolean value and narrows the TypeScript inferred type.
Expand Down

0 comments on commit 0e59220

Please sign in to comment.