diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..62f0c3c --- /dev/null +++ b/index.d.ts @@ -0,0 +1,3 @@ +declare function isSymbol(value: unknown): value is (symbol | Symbol); + +export = isSymbol; diff --git a/index.js b/index.js index dd2fc9c..1f00f80 100644 --- a/index.js +++ b/index.js @@ -8,6 +8,8 @@ var safeRegexTest = require('safe-regex-test'); if (hasSymbols) { var $symToStr = callBound('Symbol.prototype.toString'); var isSymString = safeRegexTest(/^Symbol\(.*\)$/); + + /** @type {(value: object) => value is Symbol} */ var isSymbolObject = function isRealSymbolObject(value) { if (typeof value.valueOf() !== 'symbol') { return false; @@ -15,6 +17,7 @@ if (hasSymbols) { return isSymString($symToStr(value)); }; + /** @type {import('.')} */ module.exports = function isSymbol(value) { if (typeof value === 'symbol') { return true; @@ -29,7 +32,7 @@ if (hasSymbols) { } }; } else { - + /** @type {import('.')} */ module.exports = function isSymbol(value) { // this environment does not support Symbols. return false && value; diff --git a/package.json b/package.json index 40ed47e..3b687dd 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "test": "npm run tests-only", "posttest": "npx npm@'>=10.2' audit --production", "lint": "eslint --ext=js,mjs .", + "postlint": "tsc -p . && attw -P", "version": "auto-changelog && git add CHANGELOG.md", "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" }, @@ -39,7 +40,15 @@ "safe-regex-test": "^1.0.3" }, "devDependencies": { + "@arethetypeswrong/cli": "^0.17.0", "@ljharb/eslint-config": "^21.1.1", + "@ljharb/tsconfig": "^0.2.0", + "@types/call-bind": "^1.0.5", + "@types/for-each": "^0.3.3", + "@types/has-symbols": "^1.0.2", + "@types/object-inspect": "^1.13.0", + "@types/safe-regex-test": "^1.0.2", + "@types/tape": "^5.6.5", "auto-changelog": "^2.5.0", "encoding": "^0.1.13", "es-value-fixtures": "^1.5.0", @@ -51,7 +60,8 @@ "nyc": "^10.3.2", "object-inspect": "^1.13.3", "safe-publish-latest": "^2.0.0", - "tape": "^5.9.0" + "tape": "^5.9.0", + "typescript": "next" }, "testling": { "files": "test/index.js", diff --git a/test/index.js b/test/index.js index 8fe00fd..873c928 100644 --- a/test/index.js +++ b/test/index.js @@ -14,6 +14,7 @@ test('non-symbol values', function (t) { var nonSymbols = v.nonSymbolPrimitives.concat( Object(true), Object(false), + // @ts-expect-error TS sucks with concat {}, [], /a/g, @@ -36,9 +37,12 @@ test('faked symbol values', function (t) { }); t.test('faked @@toStringTag', { skip: !hasToStringTag }, function (st) { + /** @type {{ valueOf(): unknown; [Symbol.toStringTag]?: unknown }} */ var fakeSymbol = { valueOf: function () { return Symbol('foo'); } }; fakeSymbol[Symbol.toStringTag] = 'Symbol'; st.equal(isSymbol(fakeSymbol), false, 'object with fake Symbol @@toStringTag and valueOf returning a symbol is not a symbol'); + + /** @type {{ valueOf(): unknown; [Symbol.toStringTag]?: unknown }} */ var notSoFakeSymbol = { valueOf: function () { return 42; } }; notSoFakeSymbol[Symbol.toStringTag] = 'Symbol'; st.equal(isSymbol(notSoFakeSymbol), false, 'object with fake Symbol @@toStringTag and valueOf not returning a symbol is not a symbol'); @@ -53,12 +57,14 @@ test('faked symbol values', function (t) { test('Symbol support', { skip: !hasSymbols }, function (t) { t.test('well-known Symbols', function (st) { + /** @type {(name: string) => name is Exclude} */ var isWellKnown = function filterer(name) { return name !== 'for' && name !== 'keyFor' && !(name in filterer); }; var wellKnownSymbols = Object.getOwnPropertyNames(Symbol).filter(isWellKnown); wellKnownSymbols.forEach(function (name) { - var sym = Symbol[name]; + // eslint-disable-next-line no-extra-parens + var sym = Symbol[/** @type {keyof SymbolConstructor} */ (name)]; st.equal(isSymbol(sym), true, inspect(sym) + ' is a symbol'); }); st.end(); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..707cf95 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@ljharb/tsconfig", + "compilerOptions": { + "target": "ES2021", + }, + "exclude": [ + "coverage" + ] +}