상태값을 사용하는데 있어서 객체 형태로 사용할 때,
type status = {
username: boolean;
email: boolean;
password: boolean;
password2: boolean;
};
const validateStatus: status = {
username: false,
email: false,
password: false,
password2: false,
};
이렇게 에러가 발생했다
저기서 input.id는 input태그의 id속성값을 가져온 것이다
즉, email이라는 문자열이다
<input type="text" id="email" placeholder="Enter email" />
JS방식대로 email이라는 문자열을 가져와서
문자열을 통해 객체의 프로퍼티에 접근하는 것인데
TS에서는 기본적으로 문자열을 키값으로 사용하지 않기에 에러가 발생한 것이다
그러므로 index signature을 사용해서 문제를 해결했다
type status = {
[key: string]: boolean; //index signature
};
// HTML
<input type="text" id="username" placeholder="Enter username" />
// JS
const username = document.getElementById('username');
console.log(username.value) // 해당 input태그의 내용이 출력
TS에서는 input태그에 대해 .value 속성을 사용하기 위해선
타입을 HTMLElement 대신 , HTMLInputElement로 해야 합니다
// HTML
<input type="text" id="username" placeholder="Enter username" />
// TS
// Non-null Assertion 필수
const username:HTMLElement = document.getElementById('username')!;
console.log((username as HTMLInputElement).value) // 해당 input태그의 내용이 출력
공백을 체크하고 이에 따른 에러를 보여주는 함수가 있습니다
const blankStatus = {
username: false,
email: false,
password: false,
password2: false
};
const showBlankError = (blankStatus) => {
for (let i in blankStatus) {
let inputName = i;
if (blankStatus[inputName] === false) {
switch (inputName) {
case 'username':
inputName = username;
break;
case 'email':
inputName = email;
break;
case 'password':
inputName = password;
break;
case 'password2':
inputName = password2;
break;
}
showError(inputName, '공백입니다');
continue;
}
}
};
간단히 설명하자면 , blankStatus 라는 상태가 있고
이 상태는 각 input창에 대해서 공백인지 , 값이 들어가 있는지에 대한 상태를 나타냅니다
const blankStatus: status = {
username: false,
email: false,
password: false,
password2: false,
};
blankStatus에서 값이 false인 키를 찾게 되면
( 각 키들은 getElementById로 가져온 DOM객체들을 의미한다고 가정합니다 )
이 DOM객체를 showError()로 넘겨주는 것입니다
문자열 형태로 inputName라는 변수에 넣어주고 있습니다
inputName에다가 DOM객체를 넣어줍니다
즉, inputName이라는 변수에 문자열 넣어줬다가
DOM객체를 넣어주고 있는 것입니다
그러므로 TS를 통해 아래와 같이 수정을 진행합니다
type status = {
[key: string]: boolean; //index signature
};
const blankStatus: status = {
username: false,
email: false,
password: false,
password2: false
};
const showBlankError = (blankStatus: status) => {
for (let i in blankStatus) {
let inputName: string = i;
let errorTarget: HTMLElement | undefined; **// 추가**
if (blankStatus[inputName] === false) {
switch (inputName) {
case 'username':
errorTarget = username;
break;
case 'email':
errorTarget = email;
break;
case 'password':
errorTarget = password;
break;
case 'password2':
errorTarget = password2;
break;
}
showError(errorTarget as HTMLInputElement, '공백입니다');
continue;
}
}
};
inputName은 그대로 문자열 형태로 사용하되,
errorTarget라는 DOM객체를 받는 변수를 따로 선언합니다
현재 switch문에는 default가 없으므로 ts컴파일러는
(switch문의 조건들에 걸리지 않을 경우)errorTarget에 값이 할당되지 않을 수도 있다며 에러를 뱉으므로 errorTarget의 타입을 HTMLElement 가 아닌 HTMLElement | undefined 로 해줍니다
보통 DOM객체를 받아올때 동적으로 바뀌는 부분이 아니라면,
HTMLElement라는 타입으로 바로 받아오는 것보다 최대한 타입을 상세히 작성하는 것이 좋습니다
document.getElementById('form') as HTMLElement;
document.getElementById('username') as HTMLElement;
document.getElementById('email') as HTMLElement;
document.getElementById('password') as HTMLElement;
document.getElementById('form') as HTMLFormElement;
document.getElementById('username') as HTMLInputElement;
document.getElementById('email') as HTMLInputElement;
document.getElementById('password') as HTMLInputElement;