Getting the catcode of a character assigned to a control sequence by \let

An implicit character cannot be active, nor it can have catcode 0, 5, 9, 14 or 15. Check each possibility:

\def\catcodeofimplicitchar#1{%
  \ifcat\noexpand#1\bgroup 1\else
  \ifcat\noexpand#1\egroup 2\else
  \ifcat\noexpand#1$3\else
  \ifcat\noexpand#1&4\else
  \ifcat\noexpand#1##6\else
  \ifcat\noexpand#1^7\else
  \ifcat\noexpand#1_8\else
  \ifcat\noexpand#1 10\else
  \ifcat\noexpand#1a11\else
  \ifcat\noexpand#1112\else
  -1\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
}

\let\one={ \let\two=} \let\three=$
\let\four=& \let\six=# \let\seven=^
\let\eight=_ \let\eleven=z \let\twelve=0
\begingroup\def\\#1:{\global\let\ten= #1}\\ :\endgroup
\let\thirteen=~

{\tt\meaning\one}:
\catcodeofimplicitchar\one

{\tt\meaning\two}:
\catcodeofimplicitchar\two

{\tt\meaning\three}:
\catcodeofimplicitchar\three

{\tt\meaning\four}:
\catcodeofimplicitchar\four

{\tt\meaning\six}:
\catcodeofimplicitchar\six

{\tt\meaning\seven}:
\catcodeofimplicitchar\seven

{\tt\meaning\eight}:
\catcodeofimplicitchar\eight

{\tt\meaning\ten}:
\catcodeofimplicitchar\ten

{\tt\meaning\eleven}:
\catcodeofimplicitchar\eleven

{\tt\meaning\twelve}:
\catcodeofimplicitchar\twelve

{\tt\meaning\empty}:
\catcodeofimplicitchar\empty

\ifnum\catcodeofimplicitchar\one=1 GOOD\else BAD\fi

\bye

enter image description here


You do want the same general idea as in How to get character code defined with \let (! Improper alphabetic constant), but you need to use the text of the \meaning. An example which covers three cases (space, letter, other), and which extends naturally to the other cases:

\long\def\getcatcode#1{%
  \expandafter\getcatcodeaux\meaning#1\stop
}
\edef\getcatcodeaux#1\stop{%
  \noexpand\getcatcodespace#1{}{}\detokenize{blank space}\noexpand\stop
  \noexpand\getcatcodeletter#1{}{}\detokenize{the letter}\noexpand\stop
  \noexpand\getcatcodeother#1{}{}\detokenize{the character}\noexpand\stop
}
\edef\temp{%
  \def\noexpand\getcatcodespace##1\detokenize{blank space}##2\noexpand\stop{%
    \noexpand\ifx\relax##1\relax
      10%
    \noexpand\fi
  }%
  \def\noexpand\getcatcodeletter##1\detokenize{the letter}##2\noexpand\stop{%
    \noexpand\ifx\relax##1\relax
      11%
    \noexpand\fi
  }%
  \def\noexpand\getcatcodeother##1\detokenize{the character}##2\noexpand\stop{%
    \noexpand\ifx\relax##1\relax
      12%
    \noexpand\fi
  }%
}
\temp

This is all expandable so it can go into the argument of \catcode or similar. I've not added any defensive code in case \z here is a macro which might contain the test string, a chardef, etc., but one can extend the idea.