Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: replace instanceOf with unique Symbol checks #3617

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/error/GraphQLError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,22 @@ export interface GraphQLErrorOptions {
extensions?: Maybe<GraphQLErrorExtensions>;
}

const isGraphQLErrorSymbol = Symbol.for('GraphQLError');

export function isGraphQLError(error: unknown): error is GraphQLError {
return (
typeof error === 'object' && error != null && isGraphQLErrorSymbol in error
);
}

/**
* A GraphQLError describes an Error found during the parse, validate, or
* execute phases of performing a GraphQL operation. In addition to a message
* and stack trace, it also includes information about the locations in a
* GraphQL document and/or execution result that correspond to the Error.
*/
export class GraphQLError extends Error {
readonly [isGraphQLErrorSymbol]: true = true;
/**
* An array of `{ line, column }` locations within the source GraphQL document
* which correspond to this error.
Expand Down
79 changes: 0 additions & 79 deletions src/jsutils/__tests__/instanceOf-test.ts

This file was deleted.

54 changes: 0 additions & 54 deletions src/jsutils/instanceOf.ts

This file was deleted.

8 changes: 6 additions & 2 deletions src/language/source.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { devAssert } from '../jsutils/devAssert';
import { instanceOf } from '../jsutils/instanceOf';

interface Location {
line: number;
column: number;
}

const isSourceSymbol = Symbol.for('Source');

/**
* A representation of source input to GraphQL. The `name` and `locationOffset` parameters are
* optional, but they are useful for clients who store GraphQL documents in source files.
Expand All @@ -14,6 +15,7 @@ interface Location {
* The `line` and `column` properties in `locationOffset` are 1-indexed.
*/
export class Source {
readonly [isSourceSymbol]: true = true;
body: string;
name: string;
locationOffset: Location;
Expand Down Expand Up @@ -47,5 +49,7 @@ export class Source {
* @internal
*/
export function isSource(source: unknown): source is Source {
return instanceOf(source, Source);
return (
typeof source === 'object' && source != null && isSourceSymbol in source
);
}
67 changes: 58 additions & 9 deletions src/type/definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { devAssert } from '../jsutils/devAssert';
import { didYouMean } from '../jsutils/didYouMean';
import { identityFunc } from '../jsutils/identityFunc';
import { inspect } from '../jsutils/inspect';
import { instanceOf } from '../jsutils/instanceOf';
import { keyMap } from '../jsutils/keyMap';
import { keyValMap } from '../jsutils/keyValMap';
import { mapValue } from '../jsutils/mapValue';
Expand Down Expand Up @@ -71,11 +70,17 @@ export function assertType(type: unknown): GraphQLType {
return type;
}

const isGraphQLScalarTypeSymbol = Symbol.for('GraphQLScalarType');

/**
* There are predicates for each kind of GraphQL type.
*/
export function isScalarType(type: unknown): type is GraphQLScalarType {
return instanceOf(type, GraphQLScalarType);
return (
typeof type === 'object' &&
type != null &&
isGraphQLScalarTypeSymbol in type
);
}

export function assertScalarType(type: unknown): GraphQLScalarType {
Expand All @@ -85,8 +90,14 @@ export function assertScalarType(type: unknown): GraphQLScalarType {
return type;
}

const isGraphQLObjectTypeSymbol = Symbol.for('GraphQLObjectType');

export function isObjectType(type: unknown): type is GraphQLObjectType {
return instanceOf(type, GraphQLObjectType);
return (
typeof type === 'object' &&
type != null &&
isGraphQLObjectTypeSymbol in type
);
}

export function assertObjectType(type: unknown): GraphQLObjectType {
Expand All @@ -96,8 +107,14 @@ export function assertObjectType(type: unknown): GraphQLObjectType {
return type;
}

const isGraphQLInterfaceTypeSymbol = Symbol.for('GraphQLInterfaceType');

export function isInterfaceType(type: unknown): type is GraphQLInterfaceType {
return instanceOf(type, GraphQLInterfaceType);
return (
typeof type === 'object' &&
type != null &&
isGraphQLInterfaceTypeSymbol in type
);
}

export function assertInterfaceType(type: unknown): GraphQLInterfaceType {
Expand All @@ -109,8 +126,12 @@ export function assertInterfaceType(type: unknown): GraphQLInterfaceType {
return type;
}

const isGraphQLUnionTypeSymbol = Symbol.for('GraphQLUnionType');

export function isUnionType(type: unknown): type is GraphQLUnionType {
return instanceOf(type, GraphQLUnionType);
return (
typeof type === 'object' && type != null && isGraphQLUnionTypeSymbol in type
);
}

export function assertUnionType(type: unknown): GraphQLUnionType {
Expand All @@ -120,8 +141,12 @@ export function assertUnionType(type: unknown): GraphQLUnionType {
return type;
}

const isGraphQLEnumTypeSymbol = Symbol.for('GraphQLEnumType');

export function isEnumType(type: unknown): type is GraphQLEnumType {
return instanceOf(type, GraphQLEnumType);
return (
typeof type === 'object' && type != null && isGraphQLEnumTypeSymbol in type
);
}

export function assertEnumType(type: unknown): GraphQLEnumType {
Expand All @@ -131,10 +156,16 @@ export function assertEnumType(type: unknown): GraphQLEnumType {
return type;
}

const isGraphQLInputObjectTypeSymbol = Symbol.for('GraphQLInputObjectType');

export function isInputObjectType(
type: unknown,
): type is GraphQLInputObjectType {
return instanceOf(type, GraphQLInputObjectType);
return (
typeof type === 'object' &&
type != null &&
isGraphQLInputObjectTypeSymbol in type
);
}

export function assertInputObjectType(type: unknown): GraphQLInputObjectType {
Expand All @@ -146,6 +177,8 @@ export function assertInputObjectType(type: unknown): GraphQLInputObjectType {
return type;
}

const isGraphQLListTypeSymbol = Symbol.for('GraphQLListType');

export function isListType(
type: GraphQLInputType,
): type is GraphQLList<GraphQLInputType>;
Expand All @@ -154,7 +187,9 @@ export function isListType(
): type is GraphQLList<GraphQLOutputType>;
export function isListType(type: unknown): type is GraphQLList<GraphQLType>;
export function isListType(type: unknown): type is GraphQLList<GraphQLType> {
return instanceOf(type, GraphQLList);
return (
typeof type === 'object' && type != null && isGraphQLListTypeSymbol in type
);
}

export function assertListType(type: unknown): GraphQLList<GraphQLType> {
Expand All @@ -164,6 +199,8 @@ export function assertListType(type: unknown): GraphQLList<GraphQLType> {
return type;
}

const isGraphQLNonNullTypeSymbol = Symbol.for('GraphQLNonNullType');

export function isNonNullType(
type: GraphQLInputType,
): type is GraphQLNonNull<GraphQLNullableInputType>;
Expand All @@ -176,7 +213,11 @@ export function isNonNullType(
export function isNonNullType(
type: unknown,
): type is GraphQLNonNull<GraphQLNullableType> {
return instanceOf(type, GraphQLNonNull);
return (
typeof type === 'object' &&
type != null &&
isGraphQLNonNullTypeSymbol in type
);
}

export function assertNonNullType(
Expand Down Expand Up @@ -317,6 +358,7 @@ export function assertAbstractType(type: unknown): GraphQLAbstractType {
* ```
*/
export class GraphQLList<T extends GraphQLType> {
readonly [isGraphQLListTypeSymbol]: true = true;
readonly ofType: T;

constructor(ofType: T) {
Expand Down Expand Up @@ -358,6 +400,7 @@ export class GraphQLList<T extends GraphQLType> {
* Note: the enforcement of non-nullability occurs within the executor.
*/
export class GraphQLNonNull<T extends GraphQLNullableType> {
readonly [isGraphQLNonNullTypeSymbol]: true = true;
readonly ofType: T;

constructor(ofType: T) {
Expand Down Expand Up @@ -543,6 +586,7 @@ export interface GraphQLScalarTypeExtensions {
* ```
*/
export class GraphQLScalarType<TInternal = unknown, TExternal = TInternal> {
readonly [isGraphQLScalarTypeSymbol]: true = true;
name: string;
description: Maybe<string>;
specifiedByURL: Maybe<string>;
Expand Down Expand Up @@ -701,6 +745,7 @@ export interface GraphQLObjectTypeExtensions<_TSource = any, _TContext = any> {
* ```
*/
export class GraphQLObjectType<TSource = any, TContext = any> {
readonly [isGraphQLObjectTypeSymbol]: true = true;
name: string;
description: Maybe<string>;
isTypeOf: Maybe<GraphQLIsTypeOfFn<TSource, TContext>>;
Expand Down Expand Up @@ -1021,6 +1066,7 @@ export interface GraphQLInterfaceTypeExtensions {
* ```
*/
export class GraphQLInterfaceType {
readonly [isGraphQLInterfaceTypeSymbol]: true = true;
name: string;
description: Maybe<string>;
resolveType: Maybe<GraphQLTypeResolver<any, any>>;
Expand Down Expand Up @@ -1145,6 +1191,7 @@ export interface GraphQLUnionTypeExtensions {
* ```
*/
export class GraphQLUnionType {
readonly [isGraphQLUnionTypeSymbol]: true = true;
name: string;
description: Maybe<string>;
resolveType: Maybe<GraphQLTypeResolver<any, any>>;
Expand Down Expand Up @@ -1262,6 +1309,7 @@ export interface GraphQLEnumTypeExtensions {
* will be used as its internal value.
*/
export class GraphQLEnumType /* <T> */ {
readonly [isGraphQLEnumTypeSymbol]: true = true;
name: string;
description: Maybe<string>;
extensions: Readonly<GraphQLEnumTypeExtensions>;
Expand Down Expand Up @@ -1486,6 +1534,7 @@ export interface GraphQLInputObjectTypeExtensions {
* ```
*/
export class GraphQLInputObjectType {
readonly [isGraphQLInputObjectTypeSymbol]: true = true;
name: string;
description: Maybe<string>;
extensions: Readonly<GraphQLInputObjectTypeExtensions>;
Expand Down
Loading