我有一个带字符串的类型保护,我想知道它是否是联合类型的一部分,但是如果我们在联合类型中添加新的字符串,我不想通过也添加新的字符串来管理我的类型保护: / p>
{
"$schema": "./node_modules/@angular-devkit/core/src/workspace/workspace-schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"myproject": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {
"@schematics/angular:component": {
"styleext": "scss"
}
},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist",
"index": "src/index.html",
"main": "src/main.ts",
"tsConfig": "tsconfig.app.json",
"polyfills": "src/polyfills.ts",
"assets": [
"src/favicon.ico",
"src/apple-touch-icon.png",
"src/robots.txt",
"src/manifest.json",
"src/assets"
],
"styles": [
"src/main.scss",
"node_modules/leaflet/dist/leaflet.css"
],
"scripts": []
},
"configurations": {
"production": {
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
],
"serviceWorker": true,
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
]
},
"ci": {
"progress": false
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"hmr": true,
"hmrWarning": false,
"browserTarget": "myproject:build"
},
"configurations": {
"production": {
"hmr": false,
"browserTarget": "myproject:build:production"
},
"ci": {
"progress": false
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "myproject:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"karmaConfig": "karma.conf.js",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"scripts": [],
"styles": [
"src/main.scss",
"node_modules/leaflet/dist/leaflet.css"
],
"assets": [
"src/favicon.ico",
"src/apple-touch-icon.png",
"src/robots.txt",
"src/manifest.json",
"src/assets"
]
},
"configurations": {
"ci": {
"progress": false,
"watch": false
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"tsconfig.app.json",
"tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
},
"myproject-e2e": {
"root": "e2e",
"projectType": "application",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "myproject:serve"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"e2e/tsconfig.e2e.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "myproject"
}
如果我在联合类型“ GreatAnimal”中添加Fish,则不需要更新我的类型防护来管理Fish。
我使用的是最后的打字稿版本
答案 0 :(得分:1)
const GreatAnimalList = ['Dog', 'Cat', 'Fish'] as const; // TS3.4 syntax
type GreatAnimal = typeof GreatAnimalList[number]; // 'Dog'|'Cat'|'Fish';
function isGreatAnimal(pet: string): pet is GreatAnimal {
// return GreatAnimalList.includes(pet)
return GreatAnimalList.indexOf(pet as GreatAnimal) !== -1
}
function Foo(animal: string) {
if (isGreatAnimal(animal)) {
// do something
console.log('isGreatAnimal true')
}
else {
// do something else
console.log('isGreatAnimal false')
}
}
Foo('Dog'); // isGreatAnimal true
Foo('Turtle'); // isGreatAnimal false
明天,如果您将新动物添加到GreatAnimalList
中,它将被自动添加到联合类型GreatAnimal
中。无需更改isGreatAnimal()
函数。
答案 1 :(得分:0)
您不能以编程方式使用类型,因为在已转译的JavaScript代码中将不存在它们。
例如代码的第一部分
type GreatAnimal = 'Dog' | 'Cat'
function isGreatAnimal(pet: string): pet is GreatAnimal {
return pet === 'Dog' || pet === 'Cat';
}
转换为
function isGreatAnimal(pet) {
return pet === 'Dog' || pet === 'Cat';
}
因此,您需要对GreatAnimals
进行一些编程引用才能隐式检查它们。有很多方法可以做到这一点-一个例子就是枚举(将其转换为简单的对象):
enum GreatAnimal {
DOG = "Dog",
CAT = "Cat"
}
function isGreatAnimal(pet: string): pet is GreatAnimal {
return pet in Object.values(GreatAnimal);
}
function Foo(animal: string) {
if (isGreatAnimal(animal)) {
// do something
} else {
// do something else
}
}
(请注意,此示例使用Object.values
,它是ES2017的一部分。InternetExplorer从v7开始不支持它,并且节点也支持它)。