Skip to content

Commit

Permalink
feat: Add type.isEnumLiteralType() and type.isLiteral()
Browse files Browse the repository at this point in the history
From #290
  • Loading branch information
dsherret committed Mar 27, 2018
1 parent d68b6b9 commit 56b26f8
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 5 deletions.
5 changes: 5 additions & 0 deletions docs/details/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,11 @@ type.isBooleanType();
type.isStringType();
type.isNumberType();
type.isEnumType();
type.isLiteralType();
type.isBooleanLiteralType();
type.isStringLiteralType();
type.isNumberLiteralType();
type.isEnumLiteralType();
type.isIntersectionType();
type.isInterfaceType();
type.isObjectType();
Expand Down
20 changes: 19 additions & 1 deletion src/compiler/type/Type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,13 +308,27 @@ export class Type<TType extends ts.Type = ts.Type> {
return this._hasTypeFlag(TypeFlags.Number);
}

/**
* Gets if this is a literal type.
*/
isLiteralType() {
return this._hasAnyTypeFlag(TypeFlags.Literal);
}

/**
* Gets if this is a boolean literal type.
*/
isBooleanLiteralType() {
return this._hasTypeFlag(TypeFlags.BooleanLiteral);
}

/**
* Gets if this is an enum literal type.
*/
isEnumLiteralType() {
return this._hasTypeFlag(TypeFlags.EnumLiteral);
}

/**
* Gets if this is a literal string type.
*/
Expand Down Expand Up @@ -413,10 +427,14 @@ export class Type<TType extends ts.Type = ts.Type> {
}

private _hasTypeFlag(flag: TypeFlags) {
return (this.compilerType.flags & flag) === flag;
}

private _hasAnyTypeFlag(flag: TypeFlags) {
return (this.compilerType.flags & flag) !== 0;
}

private _hasObjectFlag(flag: ObjectFlags) {
return (this.getObjectFlags() & flag) !== 0;
return (this.getObjectFlags() & flag) === flag;
}
}
49 changes: 45 additions & 4 deletions src/tests/compiler/type/typeTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,20 @@ describe(nameof(Type), () => {
// todo: move all the tests to happen in here because this will speed up the tests quite a lot
describe("fast test", () => {
const text = `
enum MyEnum {}
enum EmptyEnum { }
enum MyEnum { value, value2 }
interface MyInterface {}
class MyClass {}
let anonymousType: { str: string; };
let stringType: string;
let stringLiteralType: string;
let booleanType: boolean;
let numberType: number;
let booleanLiteralType: true;
let numberLiteralType: 5;
let stringLiteralType: 'test';
let enumType: MyEnum;
let enumType: EmptyEnum; // no clue why, but this is only an enum type for empty enums
let enumLiteralType: MyEnum.value;
let interfaceType: MyInterface;
let intersectionType: string & number;
let unionType: string | number;
Expand Down Expand Up @@ -156,6 +157,32 @@ let stringWithUndefinedAndNullType: string | undefined | null;
});
});

describe(nameof<Type>(t => t.isLiteralType), () => {
function doTest(typeName: string, expected: boolean) {
expect(typesByName[typeName].isLiteralType()).to.equal(expected);
}

it("should get when it is a boolean literal", () => {
doTest("booleanLiteralType", true);
});

it("should get when it is a string literal", () => {
doTest("stringLiteralType", true);
});

it("should get when it is an enum literal", () => {
doTest("enumLiteralType", true);
});

it("should get when it is a number literal", () => {
doTest("numberLiteralType", true);
});

it("should get when it's not", () => {
doTest("booleanType", false);
});
});

describe(nameof<Type>(t => t.isBooleanLiteralType), () => {
function doTest(typeName: string, expected: boolean) {
expect(typesByName[typeName].isBooleanLiteralType()).to.equal(expected);
Expand All @@ -170,6 +197,20 @@ let stringWithUndefinedAndNullType: string | undefined | null;
});
});

describe(nameof<Type>(t => t.isEnumLiteralType), () => {
function doTest(typeName: string, expected: boolean) {
expect(typesByName[typeName].isEnumLiteralType()).to.equal(expected);
}

it("should get when it is", () => {
doTest("enumLiteralType", true);
});

it("should get when it's not", () => {
doTest("enumType", false);
});
});

describe(nameof<Type>(t => t.isStringLiteralType), () => {
function doTest(typeName: string, expected: boolean) {
expect(typesByName[typeName].isStringLiteralType()).to.equal(expected);
Expand Down Expand Up @@ -208,7 +249,7 @@ let stringWithUndefinedAndNullType: string | undefined | null;
});

it("should get when it's not an enum type", () => {
doTest("stringType", false);
doTest("enumLiteralType", false);
});
});

Expand Down

0 comments on commit 56b26f8

Please sign in to comment.