Typescript가?를 지원합니까? 운영자? (그리고 그것이 무엇입니까?)
현재 Typescript가 안전한 탐색 연산자를 지원합니까 (또는 계획이 있습니까)?.
즉 :
var thing = foo?.bar
// same as:
var thing = (foo) ? foo.bar : null;
또한이 연산자의 일반적인 이름이 있습니까? (구글 적으로 구글하기가 어렵습니다).
TypeScript 언어 사양 에서 그것에 대한 참조를 찾을 수 없습니다 .
CoffeeScript에서이 연산자를 호출 할 때까지이를 실존 연산자 (특히 실존 연산자 의 "접근 변형 자")라고합니다.
에서 연산자에 커피 스크립트의 설명서 :
실재 연산자의 접근 자 변형을
?.
사용하여 일련의 속성에서 null 참조를 흡수 할 수 있습니다..
기본 값이 null 이거나 정의되지 않은 경우 도트 접근 자 대신 사용하십시오 .
따라서 실재 연산자 의 접근 자 변형 이이 연산자를 참조하는 적절한 방법 인 것 같습니다. TypeScript는 현재 그것을 지원하지 않는 것으로 보입니다 ( 다른 사람들 이이 기능에 대한 욕구를 표현 했지만 ).
단일만큼 좋지는 않지만 작동합니다.
var thing = foo && foo.bar || null;
원하는만큼 &&을 (를) 사용할 수 있습니다.
var thing = foo && foo.bar && foo.bar.check && foo.bar.check.x || null;
이것은 ECMAScript Optional Chaining 사양에 정의되어 있으므로 이에 대해 논의 할 때 선택적인 Chaining을 참조해야 합니다. 아마도 구현 :
const result = a?.b?.c;
이것의 길고 짧은 것은 TypeScript 팀이 ECMAScript 사양이 강화되기를 기다리고 있기 때문에 향후 구현이 중단되지 않을 수 있다는 것입니다. 만약 그들이 지금 무언가를 구현한다면, ECMAScript가 그들의 사양을 재정의한다면 큰 변화가 필요할 것입니다.
선택적 체인 사양 참조
어떤 것이 표준 JavaScript가 될 수없는 경우 TypeScript 팀은 적절하다고 생각되는대로 구현할 수 있지만 향후 ECMAScript 추가를 위해 다른 많은 기능과 마찬가지로 조기 액세스를 제공하더라도 의미를 보존하려고합니다.
바로 가기
따라서 다음과 같은 유형 변환을 포함하여 모든 JavaScript 펑키 연산자를 사용할 수 있습니다.
var n: number = +myString; // convert to number
var b: bool = !!myString; // convert to bool
수동 솔루션
그러나 다시 질문으로 돌아갑니다. JavaScript (유형 TypeScript)에서 비슷한 작업을 수행하는 방법에 대한 모호한 예가 있지만 실제로 그 기능이 우아하다는 것은 확실하지 않습니다.
(foo||{}).bar;
그래서 경우가 foo
있습니다 undefined
결과 undefined
및 경우 foo
정의라는 이름의 속성이되는 bar
값을 가지고, 결과는 그 값입니다.
나는 넣어 JSFiddle에 예 .
더 긴 예제에서는 꽤 스케치처럼 보입니다.
var postCode = ((person||{}).address||{}).postcode;
체인 기능
사양이 아직 공개되지 않은 상태에서 더 짧은 버전이 필사적이라면 경우에 따라이 방법을 사용합니다. 체인을 만족시킬 수 없거나 null / undefined로 끝나는 경우 표현식을 평가하고 기본값을 반환합니다 ( !=
여기서는 중요합니다. 여기서 약간의 긍정적 인 저글링을 원하므로 사용하고 싶지 않습니다!==
).
function chain<T>(exp: () => T, d: T) {
try {
let val = exp();
if (val != null) {
return val;
}
} catch { }
return d;
}
let obj1: { a?: { b?: string }} = {
a: {
b: 'c'
}
};
// 'c'
console.log(chain(() => obj1.a.b, 'Nothing'));
obj1 = {
a: {}
};
// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));
obj1 = {};
// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));
obj1 = null;
// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));
github에 대한 공개 기능 요청이 있습니다. 여기서 의견 / 욕구를 표현할 수 있습니다 : https://github.com/Microsoft/TypeScript/issues/16
편집 : fracz 의견 덕분에 답변을 업데이트했습니다.
TypeScript 2.0 출시 (C #의 Safe Navigator) !.
와 동일하지 않음?.
자세한 내용은이 답변을 참조하십시오.
https://stackoverflow.com/a/38875179/1057052
이것은 컴파일러에게 그 값이 null 또는 undefined가 아니라고 알려줍니다. 이 것 없는 값이 null이거나 정의되어 있는지 확인하세요.
// Compiled with --strictNullChecks
function validateEntity(e?: Entity) {
// Throw exception if e is null or invalid entity
}
function processEntity(e?: Entity) {
validateEntity(e);
let s = e!.name; // Assert that e is non-null and access name
}
?.
TypeScript 버전 2.0 에서는 연산자 가 지원되지 않습니다 .
그래서 나는 다음 기능을 사용합니다 :
export function o<T>(someObject: T, defaultValue: T = {} as T) : T {
if (typeof someObject === 'undefined' || someObject === null)
return defaultValue;
else
return someObject;
}
사용법은 다음과 같습니다.
o(o(o(test).prop1).prop2
또한 기본값을 설정할 수 있습니다.
o(o(o(o(test).prop1).prop2, "none")
Visual Studio에서 IntelliSense와 잘 작동합니다.
Phonetradr에서 작업하는 동안이 util 메소드를 작성 하여 Typescript를 사용하여 딥 속성에 안전하게 액세스 할 수 있습니다.
/**
* Type-safe access of deep property of an object
*
* @param obj Object to get deep property
* @param unsafeDataOperation Function that returns the deep property
* @param valueIfFail Value to return in case if there is no such property
*/
export function getInSafe<O,T>(obj: O, unsafeDataOperation: (x: O) => T, valueIfFail?: any) : T {
try {
return unsafeDataOperation(obj)
} catch (error) {
return valueIfFail;
}
}
//Example usage:
getInSafe(sellTicket, x => x.phoneDetails.imeiNumber, '');
//Example from above
getInSafe(foo, x => x.bar.check, null);
일반적으로이 방법을 권장하지는 않지만 (성능 문제를 조심하십시오) 스프레드 연산자를 사용하여 객체를 얕게 복제 한 다음 속성에 액세스 할 수 있습니다.
const person = { personId: 123, firstName: 'Simon' };
const firstName = { ...person }.firstName;
'firstName'의 유형이 '전파'되었기 때문에 작동합니다.
find(...)
null을 반환 할 수 있는 표현식이 있고 단일 속성이 필요할 때 이것을 가장 자주 사용 합니다.
// this would cause an error (this ID doesn't exist)
const people = [person];
const firstName2 = people.find(p => p.personId == 999).firstName;
// this works - but copies every property over so raises performance concerns
const firstName3 = { ...people.find(p => p.personId == 999) }.firstName;
typescript가 형식을 유추하는 방식과 관련된 일부 경우가있을 수 있으며 컴파일되지는 않지만 일반적으로 작동합니다.
Elvis (?) 연산자는 TypeScript 3.7에서 지원됩니다.
이 값을 사용하여 null 값을 확인할 수 있습니다 cats?.miows
. cats가 null이거나 정의되지 않은 경우 null을 반환합니다.
선택적 메소드 호출에 사용할 수도 cats.doMiow?(5)
있습니다. 존재하는 경우 doMiow를 호출합니다.
참조 : https://devblogs.microsoft.com/typescript/announcing-typescript-3-7-beta/
이전에 대답했듯이, 현재도 여전히 고려되고 있지만 지금까지 몇 년 동안 물에서 죽었습니다 .
기존 답변을 바탕으로 생각할 수 있는 가장 간결한 수동 버전이 있습니다.
function val<T>(valueSupplier: () => T): T {
try { return valueSupplier(); } catch (err) { return undefined; }
}
let obj1: { a?: { b?: string }} = { a: { b: 'c' } };
console.log(val(() => obj1.a.b)); // 'c'
obj1 = { a: {} };
console.log(val(() => obj1.a.b)); // undefined
console.log(val(() => obj1.a.b) || 'Nothing'); // 'Nothing'
obj1 = {};
console.log(val(() => obj1.a.b) || 'Nothing'); // 'Nothing'
obj1 = null;
console.log(val(() => obj1.a.b) || 'Nothing'); // 'Nothing'
누락 된 속성 오류로 인해 자동으로 실패합니다. 기본값을 결정하는 표준 구문으로 돌아가며 완전히 생략 할 수 있습니다.
이것은 간단한 경우에 효과적이지만 함수 호출과 같은 더 복잡한 작업이 필요하고 결과의 속성에 액세스하면 다른 오류도 삼킨다. 나쁜 디자인.
위의 경우 여기에 게시 된 다른 답변의 최적화 된 버전이 더 나은 옵션입니다.
function o<T>(obj?: T, def: T = {} as T): T {
return obj || def;
}
let obj1: { a?: { b?: string }} = { a: { b: 'c' } };
console.log(o(o(o(obj1).a)).b); // 'c'
obj1 = { a: {} };
console.log(o(o(o(obj1).a)).b); // undefined
console.log(o(o(o(obj1).a)).b || 'Nothing'); // 'Nothing'
obj1 = {};
console.log(o(o(o(obj1).a)).b || 'Nothing'); // 'Nothing'
obj1 = null;
console.log(o(o(o(obj1).a)).b || 'Nothing'); // 'Nothing'
더 복잡한 예 :
o(foo(), []).map((n) => n.id)
다른 방법으로 가서 Lodash '와 같은 것을 사용할 수도 있습니다 _.get()
. 간결하지만 컴파일러는 사용 된 속성의 유효성을 판단 할 수 없습니다.
console.log(_.get(obj1, 'a.b.c'));
아직 (2019 년 9 월 현재), "안전한 탐색 연산자" 가 이제 Stage 3 에 있으므로 TypeScript에서 구현되고 있습니다.
이 문제를보고 업데이트하십시오.
https://github.com/microsoft/TypeScript/issues/16
몇몇 엔진에는 초기 구현이 있습니다.
JSC : https://bugs.webkit.org/show_bug.cgi?id=200199
V8 : https://bugs.chromium.org/p/v8/issues/detail?id=9553
SM : https://bugzilla.mozilla.org/show_bug.cgi?id=1566143
( https://github.com/tc39/proposal-optional-chaining/issues/115#issue-475422578을 통해 )
지금 지원하기 위해 플러그인을 설치할 수 있습니다 :
npm install --save-dev ts-optchain
tsconfig.json에서 :
// tsconfig.json
{
"compilerOptions": {
"plugins": [
{ "transform": "ts-optchain/transform" },
]
},
}
6 개월 정도 지나면이 답변이 만료 될 것으로 예상되지만 그 동안 누군가에게 도움이 되길 바랍니다.
_.get(obj, 'address.street.name')
유형이없는 JavaScript에 적합합니다. 그러나 TypeScript 에는 실제 Elvis 연산자 가 필요 합니다!
'IT story' 카테고리의 다른 글
모바일 웹의 최대 장치 너비와 최대 너비의 차이점은 무엇입니까? (0) | 2020.04.12 |
---|---|
ADT 22로 업그레이드 한 후 라이브러리가 더 이상 APK에 추가되지 않습니다 (0) | 2020.04.12 |
이 Google Play APK 게시 오류 메시지는 무엇을 의미합니까? (0) | 2020.04.12 |
특정 폴더에서 intellij 색인 생성 비활성화 (0) | 2020.04.12 |
왜 C에서 수학 라이브러리를 연결해야합니까? (0) | 2020.04.12 |